Java学习不走弯路教程(4.用SQL查询远程服务器的文件)

 一. 前言
在前上一章教程中,介绍了用SQL查询本地文件。
程序代码请从这里下载。html

本章将在上一章的基础上,进一步扩展程序。
实际的生产环境中,通常查询的文件都放在远程的文件或数据服务器上,
下面我将带你们一步一步实现远程查询的程序。java

注:
1.本文针对初学Java的同窗训练学习思路,请不要太纠结于细节问题。
2.本文旨在达到抛砖引玉的效果,但愿你们扩展本例子,以学到更多知识的精髓。sql

二. 写给初学Java的同窗
在介绍本章内容以前,首先介绍一下Java的学习方法。
相信你们在看本文的时候已经已经拿到了各类Java学习路径,大致都是同样。
我想说的是,不要让知识的学习成为负担,Java技术种类繁多,是不管如何也学不完的。
正确的学习方法是兴趣驱动,实例驱动。
即经过一个简单的实例,不断加入所学知识进行扩展,最终扩展为一个大项目,达到系统学习,学以至用的效果。数据库

三. 步入正题
话很少说,你们本身理解,下面步入正题:服务器

 本章系统的流程以下:网络

【客户端】
1.链接远程服务器。
2.向远程服务器发送查询SQL。
3.将远程服务器反馈的查询结果输出。
app

【服务器】
1.在指定端口监听,等待客户端链接。
2.有客户端链接后,读取客户端传来的SQL。
3.调用文件查询模块,查询数据。
4.将查询的数据反馈给客户端。
5.转到步骤1。socket

工程的结构以下:


其中文件查询模块复用上一章的代码,在此不作讲解。
咱们着重介绍客户端与服务器通信的过程。学习

要想与网络中的一台机器的某个程序进行通信,首先咱们须要定位这台机器的某个程序。
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

 

完整代码请在这里下载

若有问题,你们来个人网站进行提问。
https://www.java123.vip/qa

七. 后续
本例为经过简单的SQL语句查询远程存在的文件,你们能够扩展此程序,好比用线程池来管理线程,对于异常信息的处理等。
后续章节我将在此程序的基础上,其支持JDBC接口,而后换成数据库,而且一步一步实现ORM,Service,HTTP查询等功能。

版权声明:本教程版权归java123.vip全部,禁止任何形式的转载与引用。

原帖发表于:https://www.cnblogs.com/java123vip/p/9732445.html

相关文章
相关标签/搜索