简体   繁体   English

从ByteArrayOutputStream修剪填充

[英]Trim Padding From ByteArrayOutputStream

I'm working with Amazon S3 and would like to upload an InputStream (which requires counting the number of bytes I'm sending). 我正在使用Amazon S3,并且想上传一个InputStream(这需要计算我发送的字节数)。

public static boolean uploadDataTo(String bucketName, String key, String fileName, InputStream stream) {

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

    try {
        while (stream.read(buffer) != -1) { // copy from stream to buffer
            out.write(buffer); // copy from buffer to byte array
        }
    } catch (Exception e) {
        UtilityFunctionsObject.writeLogException(null, e);
    }

    byte[] result = out.toByteArray(); // we needed all that just for length
    int bytes = result.length;
    IO.close(out);
    InputStream uploadStream = new ByteArrayInputStream(result);

    ....

}

I was told copying a byte at a time is highly inefficient (obvious for large files). 有人告诉我一次复制一个字节效率很低(对于大文件来说很明显)。 I can't make it more because it will add padding to the ByteArrayOutputStream , which I can't strip out. 我不能做得更多,因为它会向ByteArrayOutputStream添加填充,我无法删除它。 I can strip it out from result , but how can I do it safely? 我可以从result删除它,但是如何安全地进行呢? If I use an 8KB buffer, can I just strip out the right most buffer[i] == 0 ? 如果我使用8KB的缓冲区,是否可以去除最右边的buffer[i] == 0 Or is there a better way to do this? 还是有更好的方法来做到这一点? Thanks! 谢谢!

Using Java 7 on Windows 7 x64. 在Windows 7 x64上使用Java 7。

You can do something like this: 您可以执行以下操作:

int read = 0;
while ((read = stream.read(buffer)) != -1) {
    out.write(buffer, 0, read);
}

stream.read() returns the number of bytes that have been written into buffer . stream.read()返回已写入buffer的字节数。 You can pass this information to the len parameter of out.write() . 您可以将此信息传递给out.write()len参数。 So you make sure that you write only the bytes you have read from the stream. 因此,请确保只写入从流中读取的字节。

Use Jakarta Commons IOUtils to copy from the input stream to the byte array stream in a single step. 使用Jakarta Commons IOUtils一步即可将输入流复制到字节数组流。 It will use an efficient buffer, and not write any excess bytes. 它将使用有效的缓冲区,并且不会写入任何多余的字节。

If you want efficiency you could process the file as you read it. 如果您想提高效率,可以在读取文件时对其进行处理。 I would replace uploadStream with stream and remove the rest of the code. 我将用stream替换uploadStream并删除其余代码。

If you need some buffering you can do this 如果您需要一些缓冲,可以这样做

 InputStream uploadStream = new BufferedInputStream(stream);

the default buffer size is 8 KB. 默认缓冲区大小为8 KB。

If you want the length use File.length(); 如果需要长度,请使用File.length();。

 long length = new File(fileName).length();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM