上一篇学习了javaIO里面的 PipedReader 和 PipedWriter,这里对两个类做一个小小的练习:实现一个即时消息发送和接收的聊天系统(这里只实现单向发送,双向同理,定义两个管道即可)。
上一篇关于两个类源码的学习记录:https://www.cnblogs.com/coding-one/p/11351166.html
1. 定义发送者类,PipedSender.java
package com.one.jdksrc.java.io; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.PipedWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; /** * @author haoya_Coding_one * @version 1.0 * @create 2019/7/23 17:59 * @description TODO */ public class PipedSender implements Runnable { private PipedWriter pipedWriter = new PipedWriter(); private String stdInput = ""; Scanner scanner = new Scanner(System.in); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public PipedSender(){ } @Override public void run() { while (!"exit".equalsIgnoreCase(stdInput)){ try { System.out.print(simpleDateFormat.format(new Date()) + " >>:"); stdInput = scanner.nextLine(); pipedWriter.write(stdInput); } catch (IOException e) { System.out.println("发送出错了!"); } } try { pipedWriter.close(); } catch (IOException e) { System.out.println("关闭流出错了!"); } } public PipedWriter getPipedWriter() { return pipedWriter; } public void setPipedWriter(PipedWriter pipedWriter) { this.pipedWriter = pipedWriter; } public void connect(PipedReceiver pipedReceiver){ try { pipedWriter.connect(pipedReceiver.getPipedReader()); } catch (IOException e) { e.printStackTrace(); } } }
发送类很简单,使用编译器控制台终端输入,循环监听,接收到 "exit" 时停止监听,关闭流对象。
2. 定义接收者类,PipedReceiver.java
package com.one.jdksrc.java.io; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.PipedReader; import java.text.SimpleDateFormat; import java.util.Date; /** * @author haoya_Coding_one * @version 1.0 * @create 2019/7/23 18:11 * @description TODO */ public class PipedReceiver implements Runnable { private PipedReader pipedReader = new PipedReader(); private String receiveStr = ""; private char[] buff = new char[1024]; private ReceiverGui receiverGui; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public PipedReceiver(){ receiverGui = new ReceiverGui(); } @Override public void run() { int n = 0; try { n = pipedReader.read(buff); receiveStr = new String(buff, 0, n); } catch (IOException e) { System.out.println("接收出错了!"); } while (!"exit".equalsIgnoreCase(receiveStr)){ try { receiverGui.append(simpleDateFormat.format(new Date()) + " 收到:" + receiveStr); n = pipedReader.read(buff); receiveStr = new String(buff, 0, n); } catch (IOException e) { System.out.println("接收出错了!"); } } receiverGui.append(simpleDateFormat.format(new Date()) + "拜拜"); try { pipedReader.close(); } catch (IOException e) { System.out.println("关闭流出错了!"); } // System.exit(-1); } public PipedReader getPipedReader() { return pipedReader; } public void setPipedReader(PipedReader pipedReader) { this.pipedReader = pipedReader; } public static class ReceiverGui extends JFrame { private JPanel jp=new JPanel(); private JTextArea textArea = new JTextArea(); public ReceiverGui(){ jp.setLayout(null); textArea.setBounds(20, 20, 500, 500); textArea.setEditable(false); jp.add(textArea); this.add(jp); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("my"); this.setResizable(false); this.setBounds(100, 100, 600, 600); this.setVisible(true); } public void append(String string){ this.textArea.append(string); textArea.append(" "); } } }
为了清晰地分开发送方和接收方,避免打印混乱,接收类定义了一个简单的内部GUI类用于打印接收到的内容。
3. 主线程测试
上述发送者和接收者都是线程类,在main方法中开启两个线程,就可以实现发送和接收了:
public class PipedTest { public static void main(String[] args){ PipedSender pipedSender = new PipedSender(); PipedReceiver pipedReceiver = new PipedReceiver(); pipedSender.connect(pipedReceiver); System.out.println("请开始你们的表演:"); new Thread(pipedSender).start(); new Thread(pipedReceiver).start(); } }
4. 测试结果