【问题标题】:How to copy a large file in Windows XP?如何在 Windows XP 中复制大文件?
【发布时间】:2011-05-25 13:24:39
【问题描述】:

我在 Windows XP 中有一个大文件 - 38GB。 (一个虚拟机镜像)

我似乎无法复制它。

在桌面上拖动 - 出现“系统资源不足,无法完成请求的服务”的错误

使用 Java - FileChannel.transferTo(0, fileSize, dest) 对所有大于 2GB 的文件都失败

使用 Java - FileChannel.transferTo() 以 100Mb 的块在 ~18Gb 后失败

java.io.IOException: Insufficient system resources exist to complete the requested service
at sun.nio.ch.FileDispatcher.write0(Native Method)
at sun.nio.ch.FileDispatcher.write(FileDispatcher.java:44)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:72)
at sun.nio.ch.IOUtil.write(IOUtil.java:28)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:198)
at sun.nio.ch.FileChannelImpl.transferToTrustedChannel(FileChannelImpl.java:439)
at sun.nio.ch.FileChannelImpl.transferTo(FileChannelImpl.java:510)

我的意思是 - 计算机有 3GB 的 RAM。 100GB 的缓冲区应该足够了!?!?

显然 DOS 命令“copy”和“xcopy”也失败了。

(编辑)我已经尝试过 COPY 和 XCOPY - 这些都失败并出现相同的错误。 XCOPY 似乎也需要很长时间。

我听说过 Robocopy,但它不复制单个文件?

我真的觉得 Windows 现在是失败的。微软肯定听说过大于几 GB 的文件吗?

谢谢!

【问题讨论】:

  • 试试 COPY 命令还不够简单吗?那么如果你得到一个错误,报告呢?我想我用它来复制几 GB 范围内的文件,但我可能记错了。
  • 这是非常令人沮丧的一天。我正在尝试备份 1TB RAID 驱动器。一切都不正常!
  • 1) jmicron esata 驱动程序很狡猾。 2) rsync 对于本地文件副本非常非常慢(它管理 2-10MB/s),因此移至程序化版本 3) 对这些非常大的文件有问题 - 也许 rsync 可以管理,但可能需要几个小时。
  • F:\>复制 f:\vmware\Desktop\Desktop.vmdk h:\vmware\Desktop\Desktop.vmdk 覆盖 h:\vmware\Desktop\Desktop.vmdk? (是/否/全部): y 系统资源不足,无法完成请求的服务。已复制 0 个文件。 F:\>
  • @time4tea 你试过 xcopy /z 吗?

标签: java language-agnostic windows-xp filesystems large-files


【解决方案1】:

在 Java 中,不要尝试在一次操作中复制整个文件。 transferTo() 方法适用于文件块;不打算作为高级文件复制方法。在循环中调用 transferTo(),并假设 count 字节的数据将在 RAM 中(即,降低该参数以适应 RAM)。

FileChannel src = ... 
FileChannel dst = ...
final long CHUNK = 16 * 1024 * 1024; /* 16 Mb */
for (long pos = 0; pos < fileSize; ) {
  pos += src.transferTo(pos, CHUNK, dst);
}

transferTo() JavaDoc 中关于它“比简单循环更有效”的评论指的是通道到通道的通信可以比通道到用户空间到通道的优化更多。它并不意味着可以避免所有循环。

【讨论】:

  • @time4tea - 抱歉,我完全跳过了。也许每次调用都在内核级别创建一个缓冲区,并且没有及时清理它们。只是推测,但也许它会帮助您找到错误报告。
  • @time4tea - 谷歌搜索我看到一些建议,如果“块”足够小,它会起作用。见bugs.sun.com/bugdatabase/view_bug.do?bug_id=4938442
【解决方案2】:

我是 Vmware ESX 用户,我有 30 个生产虚拟机,最大的是 232GB。我将我的虚拟机实例备份到内部 SATA 驱动器上,然后每周一次将它们复制到外部 eSata。我使用 teracopy(免费),它在 3GB 的 XP 机器上平均以 45MB/s 的速度运行。

希望有所帮助 赛伦

【讨论】:

    【解决方案3】:

    嗯 - 我还没找到可行的方法。

    Windows 中的任何打包工具都不会复制该文件。拖放、COPY、XCOPY、java - 都无法复制文件。

    我想要复制文件的原因是为了在升级操作系统之前进行备份。

    最后我启动到 knoppix 并复制了它。

    【讨论】:

    • 这让我发笑 :) 我希望你升级到 Ubuntu 或其他 linux;并不是说新版本的 win 甚至 XP 都不好,只是为了这样。
    【解决方案4】:

    看看这个Hotfix,值得一试,因为我所看到的一切都表明这可以解决你的问题。

    编辑:您也可以尝试 XCOPY /Z,正如 here 指出的那样。

    【讨论】:

    • 谢谢 - 不确定。这仅适用于普通的大文件。不是离线文件——我认为这与卷影复制服务有关?
    • 他们似乎提到了离线作为示例场景;所以理论上它可能会起作用,因为问题在于复制大量数据的事实。如果是我,我会试一试……由你决定……我从来没有因为应用“不需要”的修补程序而受到影响……并不是说人们没有。
    • 嗯 - 对问题的描述完全不同,因此实际问题也可能完全不同。他们谈论机器挂起和离线文件。这不涉及挂起和脱机文件。不过还是谢谢。
    【解决方案5】:

    也可能存在硬件问题.. 我怀疑您没有太多时间,但是您可以尝试更笨的流解决方案并且不要设置大缓冲区(8-16MB 应该足够了):

    public static void copy(InputStream input, OutputStream output) throws IOException {
         byte[] buffer = new byte[1024 * 1024 * 8]; // 8MB
         int n = 0;
         while (-1 != (n = input.read(buffer))) {
             output.write(buffer, 0, n);
         }
    }
    
    public static void main(String args[]) {
    
        if (args.length != 2) {
            System.err.println("wrong argument count");
            System.exit(1);
        }
    
        FileInputStream in = null;
        FileOutputStream out = null;
    
        try {
            in = new FileInputStream(new File(args[0]));
            out = new FileOutputStream(new File(args[1]));
            copy(in, out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        if (in != null) { try { in.close(); } catch (Exception e) {}}
        if (out != null) { try { out.close(); } catch (Exception e) {}}
    
    }
    

    【讨论】:

      【解决方案6】:

      您确定文件系统实际上能够处理如此大的文件(例如 FAT32 不能)吗?查看此链接了解详情http://www.ntfs.com/ntfs_vs_fat.htm

      系统是 32 位还是 64 位?在 32 位上,您可能无法复制大于 2-4Gb 的文件。

      另外,你说 rsync 对你来说很糟糕。我有一个非常好的体验,以接近本机的速度在 2 个硬盘驱动器之间进行复制。我有很多小文件..你似乎有大块。

      您也可以尝试将大 blob 拆分为较小的 blob:)

      【讨论】:

      • 谢谢,但这不是答案。你完全没有事实地编造了这个。它是一个 32 位系统这一事实完全无关紧要 - 如果您可以制作一定大小的文件,您应该能够复制它。
      • 我在 fat32 fs 上错误地创建了一个文件,我现在无法删除,因为它最后有一个有趣的 (utf8) 字符。 Windows 只是说该文件不存在,所以是的,系统类型确实很重要......对不起,如果它不是你的答案,希望你最终找到修复:)
      【解决方案7】:
      final long CHUNK = 16 * 1024 * 1024; /* 16 Mb */
      for (long pos = 0; pos < fileSize; pos++) {   
           pos += src.transferTo(pos, CHUNK, dst); 
      } 
      

      这确实有效!只需确保您的 src 和 dst 是 FileChannel 对象(分别为输入、输出)

      【讨论】:

      • 虽然看起来有效,但实际上并没有。它在大约 20 GB 后放弃,因“资源不足”错误而失败。 :-(
      【解决方案8】:

      另一个可能的答案是 Files.copy (java NIO 2),例如:

      Path sourcePath      = Paths.get("big-file.dat");
      Path destinationPath = Paths.get("big-file-copy.dat");
      
      try {
          Files.copy(sourcePath, destinationPath,
                  StandardCopyOption.REPLACE_EXISTING);
      } catch (IOException e) {
          // something else went wrong
          e.printStackTrace();
      }
      

      【讨论】:

        猜你喜欢
        • 2014-06-17
        • 2012-02-02
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 2010-09-20
        • 2015-09-12
        • 1970-01-01
        相关资源
        最近更新 更多