2

我一直在尝试通过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 占用了大部分时间。任何人都可以提供任何建议来加快此代码的速度。

4

3 回答 3

5

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

多少数据需要多长时间?这不太可能FileOutputStream是花费时间的原因 - 更有可能是网络速度缓慢。您可能会从网络读取并并行写入文件系统,但这需要大量工作才能正确完成,而且不太可能带来那么多好处,IMO。

于 2012-04-13T19:31:56.570 回答
1

您可以在 FileOutputStream 周围尝试 BufferedOutputStream。无论您从网络读取的计数如何,它都会对所有磁盘写入产生块对齐的效果。我不认为会有很大的不同,但它可能会有所帮助。

于 2012-04-14T03:16:33.640 回答
1

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

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

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

于 2013-02-11T07:42:27.437 回答