使用TCP通过网络传输文件(加快传输速度)

时间:2012-04-13 19:25:52

标签: java performance sockets networking

我一直试图通过Socket连接发送一个大文件,但它运行缓慢,我想知道是否可以通过某种方式优化此代码以提高传输速度。

这是我发送文件的代码:

byte[] buffer = new byte[65536];
int number;

while ((number = fileInputStream.read(buffer)) != -1) {
    socketOutputStream.write(buffer, 0, number);
}

socketOutputStream.close();
fileInputStream.close();

这是我用来在另一台机器上接收文件的方法:

byte[] buffer = new byte[65536];

InputStream socketStream= clientSocket.getInputStream();
File f=new File("C:\\output.dat");

OutputStream fileStream=new FileOutputStream(f);

while ((number = socketStream.read(buffer)) != -1) {
    fileStream.write(buffer,0,number);
}

fileStream.close();
socketStream.close();

我认为写入fileStream占用了大部分时间。任何人都可以提出加快此代码的建议。

3 个答案:

答案 0 :(得分:5)

除了finally语句缺少close块之外,该代码没有明显错误。

需要多长时间才能获得多少数据? FileOutputStream不太可能花费时间 - 网络变得更加缓慢。您可能可能从网络中读取并并行写入文件系统,但要做到这一点需要做很多工作,并且它不太可能带来如此多的好处,IMO。

答案 1 :(得分:1)

您可以在FileOutputStream周围尝试BufferedOutputStream。无论您从网络读取的计数如何,它都会阻止对齐所有磁盘写入。我不希望出现重大差异,但可能会有所帮助。

答案 2 :(得分:1)

我有一个类似的问题FTP'ing大文件。我意识到使用相同的缓冲区从硬盘驱动器读取和写入网络是问题。文件系统IO喜欢更大的缓冲区,因为硬盘驱动器完成所有搜索和读取的工作要少得多。另一方面,网络更喜欢较小的缓冲区来优化吞吐量。

解决方案是使用大缓冲区从硬盘读取,然后以较小的块将此缓冲区写入网络流。

我能够在任何文件的整个长度上以100%的利用率最大化我的NIC,其中4mb读取和32kb写入。然后,您可以在服务器上执行镜像版本,方法是一次读取32kb并将其存储在内存中,然后一次将4mb写入硬盘驱动器。