1. 程式人生 > >Java學習不走彎路教程(4.用SQL查詢遠端伺服器的檔案)

Java學習不走彎路教程(4.用SQL查詢遠端伺服器的檔案)

 一. 前言在前上一章教程中,介紹了用SQL查詢本地檔案。程式程式碼請從這裡下載。

本章將在上一章的基礎上,進一步擴充套件程式。實際的生產環境中,一般查詢的檔案都放在遠端的檔案或資料伺服器上,下面我將帶大家一步一步實現遠端查詢的程式。

注:1.本文針對初學Java的同學訓練學習思路,請不要太糾結於細節問題。2.本文旨在達到拋磚引玉的效果,希望大家擴充套件本例子,以學到更多知識的精髓。

二. 寫給初學Java的同學在介紹本章內容之前,首先介紹一下Java的學習方法。相信大家在看本文的時候已經已經拿到了各種Java學習路徑,大體都是一樣。我想說的是,不要讓知識的學習成為負擔,Java技術種類繁多,是無論如何也學不完的。正確的學習方法是興趣驅動,例項驅動。即通過一個簡單的例項,不斷加入所學知識進行擴充套件,最終擴充套件為一個大專案,達到系統學習,學以致用的效果。

三. 步入正題話不多說,大家自己理解,下面步入正題:

 本章系統的流程如下:

【客戶端】 1.連線遠端伺服器。 2.向遠端伺服器傳送查詢SQL。 3.將遠端伺服器反饋的查詢結果輸出。

【伺服器】1.在指定埠監聽,等待客戶端連線。 2.有客戶端連線後,讀取客戶端傳來的SQL。 3.呼叫檔案查詢模組,查詢資料。 4.將查詢的資料反饋給客戶端。 5.轉到步驟1。

工程的結構如下:其中檔案查詢模組複用上一章的程式碼,在此不做講解。我們著重介紹客戶端與伺服器通訊的過程。

要想與網路中的一臺機器的某個程式進行通訊,首先我們需要定位這臺機器的某個程式。IP地址標識了網路中唯一的機器,這臺機器的不同的埠則標示了不同的程式。

所以,客戶端要知道連線伺服器的IP地址和埠號,來完成於伺服器的連線。 而伺服器程式之需要在特定的埠監聽,等待客戶端的連線。

伺服器連線成功後,即可通過輸入輸出流進行通訊。通訊協議分為兩種TCP/IP協議和UDP協議:前者能維持穩定的通訊,確保每一個傳送的資訊對方都收到。後者只負責傳送資訊而不管對方有沒有收到。

比如文字通訊的軟體一般採用TCP/IP協議,因為要確保傳送的每條訊息對方都能收到。音訊視訊通訊軟體一般採用UDP協議,因為缺了一點資訊也不影響對聲音影象的識別。

本專案我們採用TCP/IP協議,在Java中用ServerSocket和Socket封裝了TCP/IP協議,所以我們直接拿來用即可,感興趣的同學可以研究一下底層的實現。

四. 服務端程式我們首先看單個客戶端與伺服器的通訊流程,如下圖所示:

多個客戶端連線後,如下圖所示:

所以,我們首先做一個類ClientThread,用來負責伺服器與客戶端通訊的執行緒,程式碼如下:

 1 /**
 2  * 
 3  * @author http://www.java123.vip
 4  *
 5  */
 6 public class ClientThread implements Runnable{
 7 
 8     private Socket socket;
 9     private BufferedReader br;
10     private PrintWriter pw;
11     
12     public ClientThread(Socket socket) {
13         try {
14             
15             // 建立輸入輸出流
16             InputStream is = socket.getInputStream();
17             InputStreamReader isr = new InputStreamReader(is);
18             br = new BufferedReader(isr);
19             
20             OutputStream os = socket.getOutputStream();
21             OutputStreamWriter osw = new OutputStreamWriter(os);
22             pw = new PrintWriter(osw,true);
23             
24         } catch (IOException e) {
25             e.printStackTrace();
26         }
27     }
28     
29     public void run() {
30         
31         GetFile gf = new GetFile("c:/temp/");
32         
33         while(true) {
34             try {
35                 
36                 // 讀取客戶端的一行資訊
37                 String message = br.readLine();
38                 System.out.println("get message:"+message);
39                 
40                 // 用冒號(:)來分隔資訊的頭與內容
41                 String header = message.split(":")[0];
42                 String body = message.substring(message.indexOf(":")+1);
43                 
44                 // 查詢請求
45                 if(header.equals("query")) {
46                     String result = gf.queryFile(body);
47                     pw.println(result);
48                     
49                 // 斷開連線請求
50                 }else if(header.equals("bye")) {
51                     if(socket != null) {
52                         socket.close();
53                     }
54                     break;
55                 }
56                 
57             } catch(IOException e) {
58                 e.printStackTrace();
59             } catch (Exception e) {
60                 e.printStackTrace();
61             }
62         }
63     }
64     
65 }

伺服器實現程式碼如下:

 1 /**
 2  * 
 3  * @author http://www.java123.vip
 4  *
 5  */
 6 public class FileViewServer {
 7 
 8     private int port;
 9     
10     public FileViewServer(int port) {
11         this.port = port;
12     }
13     
14     /**
15      * 啟動伺服器
16      */
17     public void startServer() {
18         try {
19             
20             ServerSocket ss = new ServerSocket(port);
21             System.out.println("listening at port:"+port);
22             
23             while(true) {
24                 Socket s = ss.accept();
25                 System.out.println("get connection:"+s.getInetAddress().toString());
26                 
27                 // 得到連線後,啟動新執行緒負責通訊
28                 ClientThread clientThread = new ClientThread(s);
29                 new Thread(clientThread).start();
30             }
31             
32         } catch (IOException e) {
33             e.printStackTrace();
34         }
35     }
36     
37     public static void main(String[] args) {
38         FileViewServer fvs = new FileViewServer(8000);
39         fvs.startServer();
40     }
41 }

五. 客戶端程式我們需要做三個方法:  ・連線伺服器方法  ・斷開伺服器方法  ・查詢遠端檔案方法

程式碼如下:連線伺服器方法

 1     private Socket socket;
 2     private BufferedReader br;
 3     private PrintWriter pw;
 4     
 5     /**
 6      * 連線遠端伺服器
 7      * 
 8      * @param ip
 9      * @param port
10      */
11     public void connect(String ip, int port) {
12         try {
13             
14             // 連線伺服器
15             socket = new Socket(ip, port);
16             
17             // 建立輸入輸出流
18             InputStream is = socket.getInputStream();
19             InputStreamReader isr = new InputStreamReader(is);
20             br = new BufferedReader(isr);
21             
22             OutputStream os = socket.getOutputStream();
23             OutputStreamWriter osw = new OutputStreamWriter(os);
24             pw = new PrintWriter(osw,true);
25             
26         } catch (IOException e) {
27             e.printStackTrace();
28         }
29     }
30     

斷開伺服器方法

 1     
 2     /**
 3      * 斷開連線
 4      */
 5     public void disConnect() {
 6         try {
 7             
 8             // 傳送斷開連線請求
 9             pw.println("bye:bye");
10             socket.close();
11         } catch (IOException e) {
12             e.printStackTrace();
13         }
14     }
15     

查詢遠端檔案方法

 1     /**
 2      * 查詢
 3      * 
 4      * @param sql
 5      * @return
 6      */
 7     public String query(String sql) {
 8         
 9         StringBuffer result = new StringBuffer("");
10         
11         try {
12             
13             // 傳送查詢請求
14             pw.println("query:"+sql);
15             
16             while(true) {
17                 
18                 // 讀取查詢結果的每一行
19                 String queryResultLine = br.readLine();
20                 
21                 // 讀到空字串表示結果讀取完畢
22                 if("".equals(queryResultLine)) {
23                     break;
24                     
25                 // 否則,把讀到的內容存起來
26                 }else {
27                     result.append(queryResultLine);
28                     result.append("\n");
29                 }
30             }
31         } catch (IOException e) {
32             e.printStackTrace();
33         }
34         
35         // 返回查詢結果
36         return result.toString();
37     }
38     

六. 測試最後我們來測試這個程式,測試程式碼如下:

 1     
 2     /**
 3      * 測試
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         FileViewClient fvc = new FileViewClient();
 8         fvc.connect("127.0.0.1",8000);
 9         
10         String sql1 = "select * from abc.csv ";
11         String sql2 = "select id from abc.csv ";
12         String sql3 = "select id,username from abc.csv where id=2 ";
13         String sql4 = "select id,username from abc.csv where username=abc and password=aaa ";
14         String sql5 = "select id,username from abc.csv where username=abc and password=bbb ";
15         
16         System.out.println("Execute:"+sql1);
17         System.out.println(fvc.query(sql1));
18         
19         System.out.println("Execute:"+sql2);
20         System.out.println(fvc.query(sql2));
21         
22         System.out.println("Execute:"+sql3);
23         System.out.println(fvc.query(sql3));
24         
25         System.out.println("Execute:"+sql4);
26         System.out.println(fvc.query(sql4));
27         
28         System.out.println("Execute:"+sql5);
29         System.out.println(fvc.query(sql5));
30         
31         fvc.disConnect();
32     }

首先啟動伺服器,輸出如下:

listening at port:8000

啟動客戶端測試程式:客戶端輸出如下:

Execute:select * from abc.csv 
1,abc,aaa
2,def,bbb
3,xyz,ccc

Execute:select id from abc.csv 
1
2
3

Execute:select id,username from abc.csv where id=2 
2,def

Execute:select id,username from abc.csv where username=abc and password=aaa 
1,abc

Execute:select id,username from abc.csv where username=abc and password=bbb

伺服器輸出如下:

listening at port:8000
get connection:/127.0.0.1
get message:query:select * from abc.csv 
get message:query:select id from abc.csv 
get message:query:select id,username from abc.csv where id=2 
get message:query:select id,username from abc.csv where username=abc and password=aaa 
get message:query:select id,username from abc.csv where username=abc and password=bbb 
get message:bye:bye

完整程式碼請在這裡下載

七. 後續本例為通過簡單的SQL語句查詢遠端存在的檔案,大家可以擴充套件此程式,比如用執行緒池來管理執行緒,對於異常資訊的處理等。後續章節我將在此程式的基礎上,其支援JDBC介面,然後換成資料庫,並且一步一步實現ORM,Service,HTTP查詢等功能。

原帖發表於:https://www.cnblogs.com/java123vip/p/9732445.html