0

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

4

3 回答 3

2

你可以这样做:

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

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

于 2013-07-30T19:11:51.610 回答
1

使用 Jakarta Commons IOUtils 只需一步即可从输入流复制到字节数组流。它将使用有效的缓冲区,并且不会写入任何多余的字节。

于 2013-07-30T19:13:17.083 回答
0

如果您想要提高效率,您可以在阅读文件时对其进行处理。我将替换uploadStreamstream删除其余代码。

如果你需要一些缓冲,你可以这样做

 InputStream uploadStream = new BufferedInputStream(stream);

默认缓冲区大小为 8 KB。

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

 long length = new File(fileName).length();
于 2013-07-30T19:16:25.217 回答