我需要将一个非常大的文件从我的计算机上传到服务器。 (几GB) 目前,我尝试了以下方法,但我不断得到。
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3236)
我可以增加内存,但这不是我想要做的事情,因为不确定我的代码将在哪里运行。我想读取几 MB/kb 将它们发送到服务器并释放内存并重复。尝试了其他方法,例如 Files utils 或 IOUtils.copyLarge,但我遇到了同样的问题。
URL serverUrl =
new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) serverUrl.openConnection();
urlConnection.setConnectTimeout(Configs.TIMEOUT);
urlConnection.setReadTimeout(Configs.TIMEOUT);
File fileToUpload = new File(file);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("Content-Type", "application/octet-stream");
urlConnection.connect();
OutputStream output = urlConnection.getOutputStream();
FileInputStream input = new FileInputStream(fileToUpload);
upload(input, output);
//..close streams
private static long upload(InputStream input, OutputStream output) throws IOException {
try (
ReadableByteChannel inputChannel = Channels.newChannel(input);
WritableByteChannel outputChannel = Channels.newChannel(output)
) {
ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
long size = 0;
while (inputChannel.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
return size;
}
}
我认为这与 this 有关。但我不知道我做错了什么。
另一种方法是但我遇到了同样的问题:
private static long copy(InputStream source, OutputStream sink)
throws IOException {
long nread = 0L;
byte[] buf = new byte[10240];
int n;
int i = 0;
while ((n = source.read(buf)) > 0) {
sink.write(buf, 0, n);
nread += n;
i++;
if (i % 10 == 0) {
log.info("flush");
sink.flush();
}
}
return nread;
}
最佳答案
使用setFixedLengthStreamingMode根据this answer关于 Denis Tulskiy 链接到的重复问题:
conn.setFixedLengthStreamingMode((int) fileToUpload.length());
来自文档:
This method is used to enable streaming of a HTTP request body without internal buffering, when the content length is known in advance.
目前,您的代码正在尝试将文件缓冲到 Java 堆内存中,以便计算 HTTP 请求上的 Content-Length
header 。
关于java - 上传大文件时出现OOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56494852/