lda*_*dam 5 java file-io stream buffering
我正在编写一个需要通过网络发送文件的应用程序.我到目前为止只学过如何使用标准的java.net和java.io类(在我大学的第一年),所以我没有java.nio和netty以及所有那些好东西的经验.我使用Socket和ServerSocket类以及BufferedInput/OutputStreams和BufferedFile流设置了一个正常工作的服务器/客户端,如下所示:
服务器:
public class FiletestServer {
static ServerSocket server;
static BufferedInputStream in;
static BufferedOutputStream out;
public static void main(String[] args) throws Exception {
server = new ServerSocket(12354);
System.out.println("Waiting for client...");
Socket s = server.accept();
in = new BufferedInputStream(s.getInputStream(), 8192);
out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(f), 8192);
System.out.println("Sending to client...");
byte[] b = new byte[8192];
while (fin.read(b) != -1) {
out.write(b);
}
fin.close();
out.close();
in.close();
s.close();
server.close();
System.out.println("done!");
}
}
Run Code Online (Sandbox Code Playgroud)
和客户:
public class FiletestClient {
public static void main(String[] args) throws Exception {
System.out.println("Connecting to server...");
Socket s;
if (args.length < 1) {
s = new Socket("", 12354);
} else {
s = new Socket(args[0], 12354);
}
System.out.println("Connected.");
BufferedInputStream in = new BufferedInputStream(s.getInputStream(), 8192);
BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
System.out.println("Receiving...");
FileOutputStream fout = new FileOutputStream(f);
byte[] b = new byte[8192];
while (in.read(b) != -1) {
fout.write(b);
}
fout.close();
in.close();
out.close();
s.close();
System.out.println("Done!");
}
}
Run Code Online (Sandbox Code Playgroud)
起初我没有使用缓冲,并从in.read()中编写每个int.根据我在Windows 7上的网络监视器小工具,我得到了大约200kb/s的传输.然后我改变了它,但是使用了4096字节缓冲区并获得了相同的速度,但收到的文件通常比源文件大几千字节,这就是我的问题所在.我将缓冲区大小更改为8192,现在通过无线传输到我的笔记本电脑大约需要3.7-4.5mb /秒,现在已经足够快了,但是我仍然遇到文件稍微大一点的问题(这会导致它收到时,md5/sha哈希测试失败.
所以我的问题是,为了获得合适的速度,最终缓冲的正确方法是什么,最终得到完全相同的文件?让它快一点也会很好但我现在对速度感到满意.我假设一个更大的缓冲区更好到一点,我只需要找到那一点.
您忽略了实际读取的数据大小.
while (in.read(b) != -1) {
fout.write(b);
}
Run Code Online (Sandbox Code Playgroud)
即使只读取一个字节,也总是会写入8192个字节.相反,我建议使用
for(int len; ((len = in.read(b)) > 0;)
fout.write(b, 0, len);
Run Code Online (Sandbox Code Playgroud)
你的缓冲区与你的byte []的大小相同,所以它们目前并没有真正做任何事情.
大多数网络的MTU大约为1500字节,您可以在速度较慢的网络(最高1 GB)上获得性能提升,最高可达2 KB.8 KB也很好.比这更大的不太可能有所帮助.
| 归档时间: |
|
| 查看次数: |
4785 次 |
| 最近记录: |