Java学习笔记 - 第022天

每日要点

概要

两种对称性

字节 字符
InputStream Reader
OutputStream Writer
输入 输出
InputStream OutputStream
Reader Writer
read() write()

两种设计模式
1.装潢模式 - 过滤流
2.适配器模式 - 转换流

三种流
1.数据流(原始流)
2.过滤流(处理流)
2.转换流(编码转换)

原始流

FileOutputSteam - 指定文件作为输出的目的地 - 数据流(原始流)

过滤流

PrintStream - 本身没有输出的目的地要依赖数据流才能使用 - 过滤流(处理流)
过滤流通常都比数据流拥有更多的方法方便对流进行各种的操作

System中的in和out的两个流可以进行重定向
System.setOut(out);
例子1:99乘法表

    public static void main(String[] args) {
        try (PrintStream out = new PrintStream(new FileOutputStream("c:/99.txt"))) {    
    //  try (PrintStream out = new PrintStream("c:/99.txt")) {  
            // System中的in和out的两个流可以进行重定向
            // System.setOut(out);
            for (int i = 1; i <= 9; i++) {
                for (int j = 1; j <= i; j++) {
                //  System.out.printf("%d*%d=%d\t", i, j, i * j);
                    out.printf("%d*%d=%d\t", i, j, i * j);
                }
            //  System.out.println();
                out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

例子2:
其中小知识:如何在类路径下取资源文件:

    public static void main(String[] args) throws InterruptedException {
        // 如何在类路径下取资源文件
        ClassLoader loader = Test01.class.getClassLoader();
        InputStream in = loader.getResourceAsStream("resources/致橡树.txt");
    //  try (Reader reader = new FileReader("c:/致橡树.txt")) {
        try (Reader reader = new InputStreamReader(in)) {
            BufferedReader br = new BufferedReader(reader);
        //  LineNumberReader lineNumberReader = new LineNumberReader(reader);
            String str;
            while ((str = br.readLine()) != null) {
        //  while ((str = lineNumberReader.readLine()) != null) {
        //      System.out.print(lineNumberReader.getLineNumber());
                System.out.println(str);
                Thread.sleep(1000);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

转换流

转换流 - 将字节流适配成字符流 (实现从字节到字符的转换)
如果应用程序中需要做编码转换(将8位编码转换成16位编码)就需要使用转换流
例子1:普通方法

    public static void main(String[] args) {
        System.out.print("请输入: ");
        byte[] buffer = new byte[1024];
        try {
            int totalBytes = System.in.read(buffer);
            String str = new String(buffer, 0, totalBytes);
            int endIndex = str.indexOf("\r\n");
            if (endIndex != -1) {
                str = str.substring(0, endIndex);
            }
            int a = Integer.parseInt(str);
        //  System.out.println(str.toUpperCase());
            System.out.println(a > 5);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

例子2:转换流 不使用Scanner从键盘输入读取数据

    public static void main(String[] args) {
        System.out.print("请输入: ");
        try {
            // 转换流 - 将字节流适配成字符流 (实现从字节到字符的转换)
            // 如果应用程序中需要做编码转换(将8位编码转换成16位编码)就需要使用转换流
            InputStreamReader inputReader = new InputStreamReader(System.in);
            BufferedReader bufferedReader = new BufferedReader(inputReader);
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str.toUpperCase());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

序列化和反序列化

把对象写入到流中 - 序列化(serialization)
串行化/归档/腌咸菜

从流中读取对象 - 反序列化(反串行化/解归档)

serialVersionUID 相当于版本号
被transient修饰的属性不参与系列化和反序列化
private transient String tel;
注意:如果学生对象要支持序列化操作那么学生对象关联的其他对象也要支持序列化

例子1:实现对学生类和车类序列化保存对象为文件,再反序列化读取
学生类:

public class Student implements Serializable{
    private static final long serialVersionUID = 1L;  // serialVersionUID 相当于版本号
    private String name;
    private int age;
    // 被transient修饰的属性不参与系列化和反序列化
    private transient String tel;
    // 如果学生对象要支持序列化操作那么学生对象关联的其他对象也要支持序列化
    private Car car;
        
    public Student(String name, int age, String tel) {
        this.name = name;
        this.age = age;
        this.tel = tel;
    }
    
    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "name=" + name + ", age=" + age + 
                ", tel=" + tel + "," + car.toString();
    }   
}

车类:

public class Car implements Serializable{
    private static final long serialVersionUID = 1L;
    private String brand;
    private int maxSpeed;
    
    public Car(String brand, int maxSpeed) {
        this.brand = brand;
        this.maxSpeed = maxSpeed;
    }
    
    @Override
    public String toString() {
        return "car=[brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
    }   
}

序列化:

    public static void main(String[] args) {
        Student student = new Student("王大锤", 18, "13521324325");
        student.setCar(new Car("QQ", 128));
        System.out.println(student);
        try (OutputStream out = new FileOutputStream("c:/stu.data")) {
            ObjectOutputStream oos = new ObjectOutputStream(out);
            oos.writeObject(student);
            System.out.println("存档成功!");
        } catch (IOException e) { 
            e.printStackTrace();
        }
    }

反序列化:

    public static void main(String[] args) {
        try (InputStream in = new FileInputStream("c:/stu.data")) {
            ObjectInputStream ois = new ObjectInputStream(in);
            Object object = ois.readObject();
            System.out.println(object);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

昨日作业讲解

  • 作业1:九九乘法表文件输出(普通方法)
    public static void main(String[] args) {
        try (Writer writer = new FileWriter("c:/九九表.txt")) {
            for (int i = 1; i <= 9; i++) {
                for (int j = 1; j <= i; j++) {
                    String str = String.format("%d*%d=%d\t", i, j, i * j);
                    writer.write(str);
                }
                writer.write("\r\n");
            }
            System.out.println("程序执行成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 作业2:写一个方法实现文件拷贝功能
    public static void fileCopy(String source, String target) throws IOException {
        try (InputStream in = new FileInputStream(source);
                OutputStream out = new FileOutputStream(target)) {  
            byte[] buffer = new byte[512];
            int totalBytes;
            while ((totalBytes = in.read(buffer)) != -1) {
                out.write(buffer, 0, totalBytes);
            }
            
        }
    }
    
    public static void main(String[] args) {
        try {
            long start = System.currentTimeMillis();
            fileCopy("C:/Users/Administrator/Downloads/YoudaoDict.exe", "C:/Users/Administrator/Desktop");
            long end = System.currentTimeMillis();
            System.out.println((end - start) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

作业

  • **作业1:建一个文本文件 写很多话 做一个窗口 随机显示一句话 点一下换一句 **
    随机文本类:
public class RandomText {
    private List list = new ArrayList<>();
    private String str;
    private int totalRows;
    private int randomNum;
    
    public RandomText() {
        try {
            this.random();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void random() throws IOException {
        ClassLoader loader = RandomText.class.getClassLoader();
        InputStream in = loader.getResourceAsStream("resources/致橡树.txt");
        InputStreamReader reader = new InputStreamReader(in);
        BufferedReader br = new BufferedReader(reader);  
        while ((str = br.readLine()) != null) {
            list.add(str);
            totalRows += 1;
        }
    }
    
    public String randomLine() {
            randomNum = (int) (Math.random() * totalRows);
            str = list.get(randomNum);
            return str;
    }
}

窗口类:

public class MyFrame extends JFrame {
    private static final long serialVersionUID = 1L;
    private RandomText rt = new RandomText();
    private JLabel label;

    public MyFrame() {
        this.setTitle("随机话");
        this.setSize(350, 200);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        label = new JLabel(rt.randomLine());
        label.setFont(new Font("微软雅黑", Font.PLAIN, 18));
        this.add(label);
        
        JPanel panel = new JPanel();
        this.add(panel, BorderLayout.SOUTH);
        JButton button = new JButton("换一句");
        button.addActionListener(e -> {
            String command = e.getActionCommand();
            if (command.equals("换一句")) {
                label.setText(rt.randomLine());
            }
        });
        panel.add(button);
    }
    
    public static void main(String[] args) {
        new MyFrame().setVisible(true);
    }
}

你可能感兴趣的:(Java学习笔记 - 第022天)