【问题标题】:Copying a growing file in Java在 Java 中复制一个不断增长的文件
【发布时间】:2011-11-16 14:54:34
【问题描述】:

我正在尝试研究如何使用 Java 复制不断增长的文件。我想工作的一个例子如下:

  1. 从 HTTP 服务器下载文件。
  2. 我在文件下载完成之前启动了文件复制
  3. 复制开始,直到文件完全下载并复制所有内容后才结束

我使用了以下代码:

 InputStream is = new FileInputStream(sourceFile);
 OutputStream os = new FileOutputStream(targetFile);

 byte[] buf = new byte[8192]; 
 int num;
 while ((num = is.read(buf)) != -1) {
     os.write(buf, 0, num);
 }

但这只会复制迄今为止下载的内容,所以我最终得到了一个损坏的目标文件。

我也使用 BufferedInputStream 和 BufferedOutputStream 进行了测试,但也没有用。

有什么方法可以实现我想要的吗?

谢谢

【问题讨论】:

  • 下载完成后是否收到通知?
  • 不,在用户开始复制之前,系统可能完全不知道该文件。目前不支持增长文件,但我想添加对它的支持。
  • 在文件上传完成之前开始复制是否重要?

标签: java file copy


【解决方案1】:

如果您可以通过 HTTP 控制文件下载,那么您可以下载到一个临时文件,然后在下载完成后重命名该文件,从而使操作原子化。

另一种方法是让您的文件复制过程定期检查目标文件的文件大小,并且仅在文件大小稳定且不再增加时才启动复制。例如,您可以选择每秒记录一次文件大小,并且仅当大小在连续 3 次轮询尝试中保持不变时才启动复制。

【讨论】:

  • 感谢您的回答!不幸的是,文件下载与代码完全分开,文件复制是用户启动的工作的一部分。问题是对于非常大的文件,在文件完全下载之前无法启动作业,这是我想修改的。但听起来可能没那么容易。
  • 用户必须发起http下载吗?为什么不能以编程方式进行?这样可以避免问题,因为执行下载的 Java 线程会阻塞,直到数据被完全读回,但仍然可以将数据以块的形式交给另一个线程来执行实际的文件处理(或在这种情况下进行复制)。跨度>
  • 工作流程是用户将文件导入我们的系统,我正在研究是否可以添加尚未完全下载的文件。但是你说得对,对于HTTP下载的情况,可以通过让用户提供一个HTTP地址来解决,然后程序处理完整的过程,谢谢建议!
【解决方案2】:

这会很棘手,因为复制过程没有可靠的方法知道下载何时完成。您可以查看文件是否在增长,但下载可能会停止一段时间,并且您可能会错误地断定它已经完成。如果中途下载失败,您也无法知道您正在查看一个不完整的文件。

我认为您最好的选择是下载过程。如果您控制它,您可以修改它以将文件存储在其他位置或两个位置,或者在最后移动/重命名它,具体取决于您的要求。

如果您不控制下载过程,并且这是一个简单的 HTTP 下载,您可以将其替换为您可以控制的内容。

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2013-07-11
    • 2018-10-26
    • 2013-09-27
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多