2017-09-30 105 views
0

我試圖使用Java,僅使用的Java Socket編程(而不是的Apache HTTP客戶端或任何其他API) 寫這樣程序的捲曲我想擁有的選項顯示整個或唯一的響應正文,以便我向用戶索取請求。目前,想出了下面的代碼:Seprating Get請求響應主體在Java Socket編程

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     String t; 
     while ((t = br.readLine()) != null) { 
      if (t.isEmpty() && !parameters.isVerbose()) { 
       StringBuilder responseData = new StringBuilder(); 
       while ((t = br.readLine()) != null) { 
        responseData.append(t).append("\r\n"); 
       } 
       System.out.println(responseData.toString()); 
       parameters.verbose = false; 
       break; 
      } else if(parameters.isVerbose())// handle output 
       System.out.println(t); 
     } 
     br.close(); 

在詳細選項上,它工作快速,顯示了整個身體的反應,在不到一秒鐘。但是當我想知道消息的正文時,需要花費很多時間(大約10秒)才能發佈消息。 是否有人知道如何以更快的速度處理它? 謝謝。

+0

只是一個註釋:代碼的結構是很奇怪的,因爲你消耗在內部循環的整個流,因此,外循環是在非詳細情況沒用。你也可以修改你的變量名('s'和't'不是明確的名字)。 – Dici

+0

難道是冗長的開關在你的代碼中的另一個地方是活躍的?看起來你在一個案例中發送了一個像「Connection:close」這樣的頭文件,但在另一個案例中卻沒有。 – blafasel

+0

@blafasel我有完全相同的數據,只是一個布爾值差異試了一下。當我印刷整個東西時,它可以完美快速地工作。但是,只處理數據時,它變得非常慢! – Fezo

回答

0

我會假設你慢的意思是,它幾乎立即開始顯示的東西,但不斷的印刷線很長一段時間。寫到控制檯需要時間,你打印的每一行invidually而在其他的代碼路徑首先在內存中存儲整個響應,然後將它刷新到控制檯。

如果詳細響應足夠小以適應內存,則應該執行相同的操作,否則可以決定批量打印任意數量的行(即;您在內存中累積了n行,然後刷新到控制檯,清除StringBuilder並重復)。

實施我的建議最優雅的方式是使用PrintStream包裝BufferedOutputStream,本身包裝System.out。我的所有評論和建議被濃縮在下面的代碼片段:

private static final int BUFFER_SIZE = 4096; 

public static void printResponse(Socket socket, Parameters parameters) throws IOException { 
    try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     PrintStream printStream = new PrintStream(new BufferedOutputStream(System.out, BUFFER_SIZE))) { 

     // there is no functional difference in your code between the verbose and non-verbose code paths 
     // (they have the same output). That's a bug, but I'm not fixing it in my snippet as I don't know 
     // what you intended to do. 
     br.lines().forEach(line -> printStream.append(line).append("\r\n")); 
    } 
} 

如果使用任何語言結構,你不知道,隨便問更多問題。

+0

謝謝你的回答。其實,沒有什麼開始顯示幾秒鐘,然後所有的一起! 而詳細和非冗長的輸出是不同的。一個顯示整個響應,另一個顯示響應中收到的數據。 – Fezo

+0

因此讓身體的方式是體與從響應其餘部分的空行分隔。那部分是爲了取出身體。 – Fezo

+0

@Fezo我沒有看到你的代碼有任何區別。在兩種情況下都顯示所有行(非第一種情況除外,但僅當它爲空時沒有太大區別)。 – Dici