【问题标题】:Java transferFrom will not transfer more than 16mb?Java transferFrom 不会传输超过16mb?
【发布时间】:2026-01-24 19:25:01
【问题描述】:

我的 java 代码不会传输我的 25mb 文件 - 它将停止在 16mb。我尝试将 transferFrom 1 << 24 更改为 48 & 31 & 8 没有任何帮助,只是让情况变得更糟。任何想法?

ReadableByteChannel rbc = Channels.newChannel(fileURL.openStream());
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
fos.close();

【问题讨论】:

  • 48 &amp; 31 &amp; 8 背后的逻辑是什么?
  • @NPE 我在 google 上看到有人说 31 = 高达 1 GB 而 48 是两倍,但它们没有用
  • @user1888440 我之前也研究过它,但它并没有真正帮助我我不明白它有没有帮助?
  • 按设计工作。请参阅 Javadoc。

标签: java file-io java-io


【解决方案1】:

如果你使用Java7,你可以使用花哨的java.nio.file.Files 工具来复制。

 URL url = new URL("http://www.*.com");
 try (InputStream is = url.openStream()) {
    Files.copy(is, Paths.get("/tmp/output.tmp"));
 }

如果你没有,你可以使用开源工具——例如来自 Apache(在 Commons IO 中搜索 FileUtils)。

如果你想坚持当前的解决方案,你可以这样写:

BufferedInputStream bis = new BufferedInputStream(url.openStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(
    "/tmp/output2.tmp"));

byte[] buffer = new byte[1024 * 1024];
int read = 0;
while ((read = bis.read(buffer)) != -1) {
  bos.write(buffer, 0, read);
}
bos.close();
bis.close();

目的是您必须阅读直到到达流的末尾。这就是为什么您的transferFrom 只下载有限数量的数据,因为无法保证所有数据都将在一个块中传输。

【讨论】:

    【解决方案2】:

    transferFrom 不能保证在一次调用中完成,尤其是使用 URL。您需要循环调用它。

    【讨论】:

    • 使用 Long.MAX_VALUE 作为 size 参数并循环调用。
    • @EJP,在你得到这个答案之前,字体太大了。然后我说了我的第一条评论。现在它在修复字体后失去了效果:D