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

时间:2010-12-14 21:02:58

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

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

我似乎无法复制它。

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

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

使用Java - 在100Mb块中的FileChannel.transferTo()在~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的文件?

谢谢!

8 个答案:

答案 0 :(得分:2)

在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中关于它“比简单循环更有效”的评论指的是频道间通信可以比频道到用户空间更优化的事实。渠道。它意味着可以避免所有循环。

答案 1 :(得分:2)

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

希望有所帮助 Sailen

答案 2 :(得分:1)

嗯 - 我没有找到一种有效的方法。

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

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

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

答案 3 :(得分:0)

看看这个Hotfix,值得一试,因为我所看到的一切都是为了解决你的问题。

编辑:您也可以按照here的指示尝试XCOPY / Z.

答案 4 :(得分:0)

也可能存在硬件问题。 我怀疑你没有太多时间,但是你可以试试dumber流解决方案并且不设置大缓冲区(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) {}}

}

答案 5 :(得分:0)

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

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

另外,你说rsync为你准备好了。我有一个非常好的经验,在近原生速度下复制2个硬盘驱动器。我有很多小文件..你似乎在大blob上。

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

答案 6 :(得分: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对象(分别是输入,输出)

答案 7 :(得分: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();
}