• 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("
    ");
    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

  • 相关阅读:
    友好城市, 美团笔试题
    字符串计数, 美团笔试题
    公交车, 美团笔试题
    交错序列, 美团笔试题
    题目列表, 美团笔试题, 字符串数组比较
    图的遍历, 美团笔试题
    最长全1串, 美团笔试题
    外卖满减, 美团笔试题
    种花, 美团笔试题
    考试策略, 美团笔试题
  • 原文地址:https://www.cnblogs.com/java123vip/p/9732445.html
Copyright © 2020-2023  润新知