簡體   English   中英

我是否在 Java 中正確關閉了我的輸入 stream?

[英]Am I closing my input stream correctly in Java?

我創建了一個擴展 InputStream 的 class 以便我可以計算正在讀取的字節數,如果超過我定義的最大限制,則拋出異常。

這是我的 class:

    public class LimitedSizeInputStream extends InputStream
    {

        private final InputStream original;
        private final long maxSize;
        private long total;

        public LimitedSizeInputStream(InputStream original, long maxSize)
        {
            this.original = original;
            this.maxSize = maxSize;
        }

        @Override
        public int read() throws IOException
        {
            int i = original.read();
            if (i >= 0)
            {
                incrementCounter(1);
            }
            return i;
        }

        @Override
        public int read(byte b[]) throws IOException
        {
            return read(b, 0, b.length);
        }

        @Override
        public int read(byte b[], int off, int len) throws IOException
        {
            int i = original.read(b, off, len);
            if (i >= 0)
            {
                incrementCounter(i);
            }
            return i;
        }

        private void incrementCounter(int size) throws IOException
        {
            total += size;
            if (total > maxSize)
            {
                throw new IOException("InputStream exceeded maximum size in bytes.");
            }
        }
    }

這來自: Copy InputStream, abort operation if size超出limit ,我正在實現一個Jersey API 如果用戶上傳的文件太大,它需要失敗。

這是我的資源 class:

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Path("/test")
    public Response load(
        @Context HttpServletRequest request,
        @FormDataParam(FILE_FIELD) FormDataBodyPart file)
    {
      if (request.getContentLength() > MAX_FILE_SIZE_IN_BYTES)
        {
            // fail fast handle failure
        }

      try (InputStream stream = new LimitedSizeInputStream(
           file.getValueAs(InputStream.class), MAX_FILE_SIZE_IN_BYTES))
        {
            // some logic
        }
      catch (IOException e)
        {
            // handle failure
        }
}

我在我的嘗試資源中包裝了 LimitedSizeInputStream,所以我認為 stream 應該正確關閉。 對於關閉是否正確處理,或者我是否在技術上通過 LimitedSizeInputStream 和 file.getValueAs(InputStream.class) 打開兩個輸入流並且只有一個正在關閉,我只是有點困惑?

try-with-resources 只關閉聲明的資源。 所以只會關閉metadataStream

您應該在LimitedSizeInputStream中實現close方法來關閉原始 stream。

@Override
public void close() throws IOException {
    original.close();
}

如果LimitedSizeInputStream擴展InputStream並包裝另一個 stream,那么@areus 的解決方案是最好的。

另一種方法是擴展FilterInputStream ,如下所示:

public class LimitedSizeInputStream extends FilterInputStream
{
    private final long maxSize;
    private long total;

    public LimitedSizeInputStream(InputStream original, long maxSize)
    {
        super(original);
        this.original = original;
        this.maxSize = maxSize;
    }

    // use 'this.in' instead of 'this.original'
    // at least one of the 'read' methods needs to be overridden.
}

請注意, FilterInputStream提供了可能證明有用的 API 方法的默認實現。

javadoc提供了默認方法實現的詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM