使用Java通过网络复制文件数据非常慢

时间:2011-12-15 12:50:13

标签: java networking

我的代码必须从它加载的每个文件中读取一部分数据,通常大约100,000字节。这适用于本地文件,但对我的wifi网络来说可能非常慢,即使我的网络似乎足够(但速度不快)

所以我创建了这个简单的测试:

public void testDataCopySpeed() throws Exception
    {
        File file = new File("Z:\\TestFile.mp3");
        System.out.println("start:"+new Date());
        FileChannel fc = new FileInputStream(file).getChannel();
        ByteBuffer bb = ByteBuffer.allocate(500000);         //1/2 MB
        fc.read(bb);
        System.out.println("end:"+new Date());
    }

在本地文件上花费不到一秒钟,但在网络文件上花费超过一分钟。

所以我接着尝试测试我的网络速度,我看不出如何测试wifi,但我使用http://myspeedtestonline.com/测试了互联网上传/下载速度,假设这比我的实际wifi网络慢。它给了我:

下载速度:512KB /秒 上传速度:40KB /秒

我在另一台计算机上运行了相同的测试,但速度相似

那么我怎么能在一秒内下载1/2 MB的数据,但是从Java中的一个文件复制1 / 2MB的数据可能需要一分钟,该文件存放在NAS上。 ?

编辑:所以我在下面有几个很好的答案,我真正想知道的是从一组文件中访问前10万个字节的最佳方法是什么,这些文件只对本地和网络文件,或者我应该有不同的代码,具体取决于它是否没有联网。修复网络并不是真正的解决方案,我可能能够修复我的网络但是这个软件必须在任何计算机上工作,我的许多客户可能没有最终网络,也没有修复网络问题的技能。

2 个答案:

答案 0 :(得分:1)

你可以试一下内存映射文件吗?

File file = new File("Z:/TestFile.mp3");
System.out.println("start:"+new Date());
FileChannel fc = new FileInputStream(file).getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
System.out.println("end:"+new Date());

这可能只会显得更快,或者可能有助于隐藏需要多长时间。

答案 1 :(得分:0)

你在这里比较苹果和橘子。当您访问http://myspeedtestonline.com/时,Flash插件可能正在使用HTTP协议,但肯定不是CIFS。

当您在NAS上寻址文件时,最有可能使用CIFS协议。众所周知,该协议存在性能问题,尤其是在消费类设备(Buffalo驱动器等)上实现时。

有时MTU大小太大,导致数据包碎片化并重新发送。

所以我的猜测是Java在这种情况下不是正确的地址。但无论如何,您无法使用简单的Java程序分析问题。你应该使用网络嗅探器。