gpt4 book ai didi

java - 如何正确缓冲 Java 输入/输出/文件流?

转载 作者:行者123 更新时间:2023-12-04 19:13:53 27 4
gpt4 key购买 nike

我正在编写一个需要通过网络发送文件的应用程序。到目前为止(在我大学的第一年),我只学过如何使用标准的 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!");
}
}

和客户:
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!");
}
}

起初我没有使用缓冲,而是从 in.read() 中写入每个 int。根据我在 Windows 7 上的网络监视器小工具,这让我获得了大约 200kb/s 的传输速度。然后我按照上面的方法更改了它,但使用了 4096 字节缓冲区并获得了相同的速度,但收到的文件通常比源文件大几 KB,这就是我的问题所在。我将缓冲区大小更改为 8192,现在我通过无线传输到我的笔记本电脑大约 3.7-4.5mb/sec,这对于现在来说已经足够快了,但是我仍然遇到文件变大的问题(这会导致它接收时无法通过 md5/sha 哈希测试)。

所以我的问题是什么是缓冲以获得不错的速度并最终在另一侧得到完全相同的文件的正确方法是什么?让它走得更快一点也很好,但我对现在的速度很满意。我假设更大的缓冲区在某种程度上更好,我只需要找到那个点。

最佳答案

您忽略了实际读取的数据大小。

while (in.read(b) != -1) {
fout.write(b);
}

即使只读取一个字节,也将始终写入 8192 个字节。相反,我建议使用
for(int len; ((len = in.read(b)) > 0;)
fout.write(b, 0, len);

您的缓冲区与您的 byte[] 大小相同,因此目前它们实际上并没有做任何事情。

大多数网络的 MTU 大约为 1500 字节,您可以在速度较慢的网络(最多 1 GB)上获得最多 2 KB 的性能提升。 8 KB 也不错。比这更大不太可能有帮助。

关于java - 如何正确缓冲 Java 输入/输出/文件流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12247542/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com