这段代码使Stream关闭,但我不知道为什么。它嵌入在Apache Cloudstack中,每当我尝试上传大文件(例如20GB及更多)时,都会引发Exception。
由于catch块中的getMessage(),我什至不确定RandomAccessFile()是否抛出IOException或getResponseBodyAsStream()。
不幸的是,重新编译和测试这段代码非常困难,因此,我非常感谢任何提示,可能在这里出问题。
我尝试将其缩小一些,但是您可以在此处找到完整版本: https://github.com/apache/cloudstack/blob/1d05fead49f5c856257a741b07122f5633d2e359/core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java#L184
try (InputStream in = request.getResponseBodyAsStream();
RandomAccessFile out = new RandomAccessFile(file, "rw"); ) {
out.seek(localFileSize);
if (copyBytes(file, in, out)) return 0;
} finally { /* in.close() and out.close() */ }
return totalBytes;
} catch (HttpException hte) {
status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
errorString = hte.getMessage();
} catch (IOException ioe) {
status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
errorString = ioe.getMessage();
} finally {
if (status == Status.UNRECOVERABLE_ERROR &&
file.exists() && !file.isDirectory()) {
file.delete();
}
request.releaseConnection();
if (callback != null) {
callback.downloadComplete(status);
}
}
private boolean copyBytes(File file,
InputStream in,
RandomAccessFile out) throws IOException {
int bytes;
byte[] block = new byte[CHUNK_SIZE];
long offset = 0;
boolean done = false;
VerifyFormat verifyFormat = new VerifyFormat(file);
status = Status.IN_PROGRESS;
while (!done && status != Status.ABORTED && offset <= remoteSize) {
if ((bytes = in.read(block, 0, CHUNK_SIZE)) > -1) {
offset = writeBlock(bytes, out, block, offset);
if (!verifyFormat.isVerifiedFormat() &&
(offset >= 1048576 || offset >= remoteSize)) {
//let's check format after we get 1MB or full file
verifyFormat.invoke();
if (verifyFormat.isInvalid()) return true;
}
} else {
done = true;
}
}
out.getFD().sync();
return false;
}