我正在使用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。
答案 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();