Java程式碼
<ol class=" list-paddingleft-2"> <li><p>public void handleConnection(Socket connectionToHandle) { </p></li> <li><p>new Thread(new ConnectionHandler(connectionToHandle)).<br>start(); </p></li> <li><p>} </p></li> <li><p>public void handleConnection(Socket connectionToHandle) { </p></li> <li><p>new Thread(new ConnectionHandler(connectionToHandle)).<br>start(); </p></li> <li><p>} </p></li> </ol>
我們對 RemoteFileServer 所做的大幅改變就體現在這個方法上。我們仍然在伺服器接受一個連線之後呼叫 handleConnection() ,但現在我們把該 Socket 傳遞給 ConnectionHandler 的一個實例,它是 Runnable 的。我們用 ConnectionHandler 創建一個新 Thread 並啟動它。 ConnectionHandler 的 run() 方法包含Socket 讀取/寫入和讀取 File 的程式碼,這些程式碼原來在 RemoteFileServer 的 handleConnection() 中。
4. 處理連線:第 2 部分
這裡是 ConnectionHandler 類別的結構:
Java程式碼
import java.io.*; import java.net.*; public class ConnectionHandler implements Runnable{ Socket socketToHandle; public ConnectionHandler(Socket aSocketToHandle) { socketToHandle = aSocketToHandle; } public void run() { } } import java.io.*; import java.net.*; public class ConnectionHandler implements Runnable{ Socket socketToHandle; public ConnectionHandler(Socket aSocketToHandle) { socketToHandle = aSocketToHandle; } public void run() { }
這個助手類別相當簡單。跟我們到目前為止的其它類別一樣,我們導入 java.net 和 java.io 。這個類別只有一個實例變數 socketToHandle ,它保存由該實例處理的 Socket 。類別的建構器用一個 Socket 實例作參數並將它賦給 socketToHandle 。
請注意該類別實作了 Runnable 介面。實作這個介面的類別都必須實作 run() 方法,我們的類別就是這樣做的。稍後我們將探討 run() 的細節。現在只需知道它將實際處理連接,所使用的程式碼跟我們先前在 RemoteFileServer 類別中看到的是一樣的。
實作run()
這裡我們實作run() 方法,它將攫取我們的連接的流,用它來讀寫該連接,並在任務完成之後關閉它:
Java程式碼
public void run() { try { PrintWriter streamWriter = new PrintWriter(socketToHandle.getOutputStream()); BufferedReader streamReader = new BufferedReader(new InputStreamReader(socketToHandle.getInputStream())); String fileToRead = streamReader.readLine(); BufferedReader fileReader = new BufferedReader(new FileReader(fileToRead)); String line = null; while ((line = fileReader.readLine()) != null) streamWriter.println(line); fileReader.close(); streamWriter.close(); streamReader.close(); } catch (Exception e) { System.out.println("Error handling a client: " + e); } } public void run() { try { PrintWriter streamWriter = new PrintWriter(socketToHandle.getOutputStream()); BufferedReader streamReader = new BufferedReader(new InputStreamReader(socketToHandle.getInputStream())); String fileToRead = streamReader.readLine(); BufferedReader fileReader = new BufferedReader(new FileReader(fileToRead)); String line = null; while ((line = fileReader.readLine()) != null) streamWriter.println(line); fileReader.close(); streamWriter.close(); streamReader.close(); } catch (Exception e) { System.out.println("Error handling a client: " + e); } }
ConnectionHandler的run() 方法所做的事情就是RemoteFileServer 上的handleConnection() 所做的事情。首先,我們把 InputStream 和 OutputStream 分別包裝(用 Socket 的 getOutputStream() 和 getInputStream() )進 BufferedReader 和 PrintWriter 。然後我們用這些程式碼逐行地讀取目標檔:
Java程式碼
FileReader fileReader = new FileReader(new File(streamReader.readLine())); BufferedReader bufferedFileReader = new BufferedReader(fileReader); String line = null; while ((line = bufferedFileReader.readLine()) != null) { streamWriter.println(line); } FileReader fileReader = new FileReader(new File(streamReader.readLine())); BufferedReader bufferedFileReader = new BufferedReader(fileReader); String line = null; while ((line = bufferedFileReader.readLine()) != null) { streamWriter.println(line); }
請記住我們應該從客戶機取得一個有效的檔案路徑,這樣用該路徑名建構一個新File ,把它包裝進FileReader 以處理讀取文件的操作,然後把它包裝進BufferedReader 以讓我們逐行地讀該文件。我們在 Java while迴圈語句中呼叫 BufferedReader 上的 readLine() 直到不再有要讀的行。請記注,對 readLine() 的呼叫將造成阻塞,直到有位元組來到為止。我們取得一些位元組之後就把它們放到本地的 line 變數中,然後寫出到客戶機上。
以上是Java中如何利用while迴圈語句處理關鍵環節的詳細內容。更多資訊請關注PHP中文網其他相關文章!