[英]Am I closing my input stream correctly in Java?
I created a class that extends InputStream so that I can keep count of the number of bytes being read and throw an exception if it exceeds a max limit that I define.我创建了一个扩展 InputStream 的 class 以便我可以计算正在读取的字节数,如果超过我定义的最大限制,则抛出异常。
Here is my 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.");
}
}
}
This is coming from: Copy InputStream, abort operation if size exceeds limit , I am implementing a Jersey API that needs to fail if a user is uploading a file that is too large.这来自: Copy InputStream, abort operation if size超出limit ,我正在实现一个Jersey API 如果用户上传的文件太大,它需要失败。
Here is my resource class:这是我的资源 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
}
}
I wrapped LimitedSizeInputStream in my try resource so I think the stream should close properly.我在我的尝试资源中包装了 LimitedSizeInputStream,所以我认为 stream 应该正确关闭。 I'm just a bit confused as to whether the close is handled correctly or if I'm technically opening two input streams through LimitedSizeInputStream and file.getValueAs(InputStream.class) and only one is closing?
对于关闭是否正确处理,或者我是否在技术上通过 LimitedSizeInputStream 和 file.getValueAs(InputStream.class) 打开两个输入流并且只有一个正在关闭,我只是有点困惑?
The try-with-resources only closes the declared resource. try-with-resources 只关闭声明的资源。 So will only close
metadataStream
.所以只会关闭
metadataStream
。
You should implement the close
method in LimitedSizeInputStream
to close the original stream.您应该在
LimitedSizeInputStream
中实现close
方法来关闭原始 stream。
@Override
public void close() throws IOException {
original.close();
}
If LimitedSizeInputStream
extends InputStream
and wraps another stream, then @areus's solution is the best one.如果
LimitedSizeInputStream
扩展InputStream
并包装另一个 stream,那么@areus 的解决方案是最好的。
An alternative approach would be to extend FilterInputStream
, like this:另一种方法是扩展
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.
}
Note that FilterInputStream
provides default implementations of the API methods that may prove useful.请注意,
FilterInputStream
提供了可能证明有用的 API 方法的默认实现。
The javadoc provides details of what the default method implementations do. javadoc提供了默认方法实现的详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.