簡體   English   中英

如何正確緩沖Java輸入/輸出/文件流?

[英]How can I buffer my Java input/output/file streams properly?

我正在編寫一個需要通過網絡發送文件的應用程序。 到目前為止(在我大學的第一年),我僅被教過如何使用標准的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字節的緩沖區,並獲得了相同的速度,但是接收到的文件通常比源文件大幾千字節,這就是我的問題。 我將緩沖區大小更改為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。 大於此值不太可能會有所幫助。

如果您確實想使其“如此完美”,則應查看try-catch-with-resources語句java.nio包 (或任何nio派生的庫)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM