如何在Windows XP中复制大文件?

3

我有一个在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大小的文件,但我可能记错了。 - MJB
今天真是让人沮丧的一天。我正在尝试备份一个1TB的RAID驱动器,但所有的东西都不起作用! - time4tea
  1. jmicron esata驱动程序有问题。
  2. 对于本地文件复制,rsync非常非常慢(它只能达到2-10MB/s),因此转向编程版本。
  3. 遇到这些非常大的文件有问题 - 也许rsync可以处理,但可能需要几个小时。
- time4tea
我正在尝试这个过程。 - time4tea
哦 - 但它失败了。F:>xcopy /z f:\vmware\Desktop\Desktop.vmdk h:\vmware\Desktop\Desktop.vmdk H:\vmware\Desktop\Desktop.vmdk是指目标上的文件名还是目录名 (F =文件,D =目录)?f F:\vmware\Desktop\Desktop.vmdk 文件创建错误 - 没有足够的系统资源来完成请求的服务。 - time4tea
显示剩余4条评论
8个回答

2
在Java中,不要尝试一次性复制整个文件。transferTo() 方法针对文件的块进行操作,并不是高级文件复制方法。在循环中调用 transferTo() 方法,并假设 count 字节的数据将存储在RAM中(即降低该参数以确保能够容易地适应RAM)。请参考transferTo()
FileChannel src = ... 
FileChannel dst = ...
final long CHUNK = 16 * 1024 * 1024; /* 16 Mb */
for (long pos = 0; pos < fileSize; ) {
  pos += src.transferTo(pos, CHUNK, dst);
}
< p >在transferTo() JavaDoc中关于它比"简单循环"更高效的评论是指通道到通道的通信可以比通道到用户空间到通道的通信更加优化。这并不意味着所有循环都可以避免。


@time4tea - 抱歉,我完全忽略了这个。也许每次调用都会在内核层创建一个缓冲区,并且它们没有及时清理。只是猜测,但也许能帮助你找到一个错误报告。 - erickson
@time4tea - 在谷歌上搜索,我看到一些建议说如果“块”足够小,它就可以工作。请参见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4938442 - erickson

2
我是一位VMware ESX用户,我有30个生产虚拟机,其中最大的一个为232GB。我将我的虚拟机实例备份到内部SATA驱动器上,然后每周复制到外部eSata驱动器。我使用免费的teracopy,在一台拥有3GB内存的XP电脑上平均运行速度为45MB/s。
希望这能帮到您。 Sailen

1

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

Windows中的所有打包工具都无法复制该文件。拖放、COPY、XCOPY、Java等都无法复制该文件。

我想复制该文件是为了在升级操作系统之前备份。

最终,我启动了Knoppix并将其复制了。


这让我笑了 :) 我希望你升级到Ubuntu或其他Linux;不是因为新版本的Win甚至XP不好,而只是为了这样做。 - Adrian

0

另一个可能的答案是使用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();
}

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

这个是有效的!只要确保你的src和dst是FileChannel对象(分别为输入和输出)


2
虽然看起来它能工作,但实际上并不行。在大约20GB左右就会放弃,并显示“资源不足”的错误信息。 :-( - time4tea

0

也可能存在硬件问题.. 我怀疑你没有太多时间,不过你可以尝试使用更简单的流解决方案,并且不要设置大缓冲区(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) {}}

}

0

看看这个热补丁,值得一试,因为我看到的所有信息都指向它是解决你问题的方法。

编辑:你也可以尝试这里提到的XCOPY /Z。


谢谢 - 不确定。这只是针对普通的大文件,而不是离线文件 - 我认为这与卷影复制服务有关? - time4tea
他们似乎提到了离线作为示例场景;因此理论上它可能有效,问题在于复制大量数据的事实。如果是我,我会试一试...由你决定...我从未因应用“不必要”的热修补而受到影响...虽然也不能说没有人受到过。 - Aaron McIver
好的 - 那里描述的问题完全不同,因此实际问题很可能也完全不同。他们谈论机器挂起和离线文件。这不涉及挂起和离线文件。还是谢谢。 - time4tea

0

你确定文件系统能够处理如此大的文件吗(例如FAT32不能)?请查看此链接以获取详细信息http://www.ntfs.com/ntfs_vs_fat.htm

系统是32位还是64位?在32位系统上,您可能会遇到复制大于2-4GB的文件的问题。

此外,您说rsync对您来说很糟糕。我用它拷贝两个硬盘之间的文件速度接近本机速度,体验非常好。我有很多小文件...而你似乎只有一个大块。

您也可以尝试将大块分成较小的块:)


谢谢,但这不是一个答案。你完全是凭空捏造的,没有任何事实依据。它是32位系统完全无关紧要 - 如果你可以制作一个特定大小的文件,你应该能够复制它。 - time4tea
我不小心在一个 FAT32 文件系统上创建了一个文件,现在无法删除,因为它在结尾处有一个有趣的(UTF8)字符。Windows 简单地说这个文件不存在,所以是的,系统类型确实很重要... 如果我的答案不正确的话,非常抱歉,希望你最终能找到解决方法 :) - Quamis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接