从ByteArrayOutputStream修剪填充

时间:2013-07-30 19:06:08

标签: java amazon-s3 stream bytearray

我正在使用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);

    ....

}

我被告知一次复制一个字节是非常低效的(对于大文件来说很明显)。我无法做到更多,因为它会为ByteArrayOutputStream添加填充,我无法删除。我可以从result删除它,但我怎么能安全地完成它?如果我使用8KB缓冲区,我可以删除最右边的buffer[i] == 0吗?或者有更好的方法吗?谢谢!

在Windows 7 x64上使用Java 7。

3 个答案:

答案 0 :(得分:2)

您可以这样做:

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

stream.read()返回已写入buffer的字节数。您可以将此信息传递给len的{​​{1}}参数。因此,请确保只写入从流中读取的字节。

答案 1 :(得分:1)

使用Jakarta Commons IOUtils在一个步骤中从输入流复制到字节数组流。它将使用有效的缓冲区,而不是写任何多余的字节。

答案 2 :(得分:0)

如果您想要效率,可以在阅读时处理文件。我会将uploadStream替换为stream并删除其余代码。

如果您需要缓冲,可以执行此操作

 InputStream uploadStream = new BufferedInputStream(stream);

默认缓冲区大小为8 KB。

如果你想长度使用File.length();

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