Java:如何在不分配完整内存之前从InputStream计算读取字节数

时间:2016-06-07 11:34:48

标签: java stream limit

我有一个Java后端,用户可以在其中上传文件。我想将这些上传的文件限制为最大大小,并希望在上传发生时检查上传的字节数量,并在达到限制时立即中断传输。

目前我在分配之前使用InputStream.available()来确定估计的大小,但这似乎被认为是不可靠的。

有什么建议吗?

6 个答案:

答案 0 :(得分:1)

当您想知道已读取了多少字节时,可以使用Guava's CountingInputstreamApache IO's CountingInputStream

另一方面,当您想要在达到某个限制时立即停止上传时,只需在读取字节块时进行计数,并在超出限制时关闭流。

答案 1 :(得分:1)

int count = 1;
InputStream stream;
if (stream.available() < 3) {
count++;
}
Result:
[0][1]{2][3] 
 1  1  1  1

答案 2 :(得分:0)

您不必在'之前'分配[e]完整内存。只需使用正常大小的缓冲区,比如说8k,然后执行正常的复制循环,计算总传输量。如果超出配额,请停止并销毁输出文件。

答案 3 :(得分:-1)

如果您正在使用servlet和多部分请求,则可以执行此操作:

Point::Enum
  x, y
  constructor ( x, y ) {
    ...
  }

  bottom_left = Point ( 0, 0 )
  top_left = Point ( 0, 100 )
  top_right = Point ( 100, 100 )
  bottom_right = Point ( 100, 0 )

答案 4 :(得分:-1)

我的解决方案如下:

public static final byte[] readBytes (InputStream in, int maxBytes)
throws IOException {
    byte[] result               = new byte[maxBytes];
    int bytesRead               = in.read (result);
    if (bytesRead > maxBytes) {         
        throw new IOException   ("Reached max bytes (" + maxBytes + ")");
    }       
    if (bytesRead < 0) {            
        result                  = new byte[0];
    }
    else {
        byte[] tmp              = new byte[bytesRead];
        System.arraycopy        (result, 0, tmp, 0, bytesRead);
        result                  = tmp;
    }       
    return result;
}

修改 新变种

public static final byte[] readBytes (InputStream in, int bufferSize, int maxBytes)
throws IOException {

    ByteArrayOutputStream out       = new ByteArrayOutputStream();
    byte[] buffer                   = new byte[bufferSize];

    int bytesRead                   = in.read (buffer);
    out.write                       (buffer, 0, bytesRead);

    while (bytesRead >= 0) {

        if (maxBytes > 0 && out.size() > maxBytes) {

            String message          = "Reached max bytes (" + maxBytes + ")";
            log.trace               (message);
            throw new IOException   (message);
        }

        bytesRead                   = in.read (buffer);

        if (bytesRead < 0)
            break;

        out.write                   (buffer, 0, bytesRead);
    }

    return out.toByteArray();
}

答案 5 :(得分:-2)

read的所有方法实现都返回读取的字节数。因此,您可以启动计数器并在每次读取时适当增加它,以查看到目前为止您已读取的字节数。可用方法()允许您查看此时缓冲区中可读取的字节数,并且与文件的总大小无关。虽然这种方法可以非常有用,但是为了优化您的读数,每次您都可以请求读取现有的块并避免阻塞。同样在你的情况下,你可以在阅读之前预测,即将到来的读数后你将拥有的字节数是否超过你的限制,因此你甚至可以在读取下一个块之前取消它