Java学习 day18_IO

简化流FileReader

用来读取字符文件的便捷类

继承关系

在这里插入图片描述

构造方法:

FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader

成员方法:

3个read方法:

package com.cskaoyan.charstream;

import java.io.FileReader;
import java.io.IOException;

/**
 * @description:
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo3 {
    public static void main(String[] args) throws IOException {
        // 创建FileReader对象
        FileReader reader = new FileReader("a.txt");
        // read
        //int readData = reader.read();
        //System.out.println(((char) readData));
        // 多个字符
        char[] chars = new char[1024];
        int readCount = reader.read(chars);
        System.out.println(new String(chars,0,readCount));
        // close
        reader.close();

    }
}

转换流 VS 简化流
  • 使用角度上看 简化流比转化流更方便
  • 继承关系上看,简化流是转化流的直接子类
  • 编解码角度上看,简化流不能指定编解码,只能使用默认的编解码,对于转化流来讲 可以指定编解码(最重要的区别)
package com.cskaoyan.charstream;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @description:
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo4 {
    public static void main(String[] args) throws IOException {
        // 简化流读取
        //read1();
        // 转化流读取
        InputStreamReader in =
                new InputStreamReader(
                        new FileInputStream("aa.txt"),"gbk");
        // read
        char[] chars = new char[1024];
        int readCount = in.read(chars);
        System.out.println(new String(chars,0,readCount));
        in.close();
    }

    private static void read1() throws IOException {
        FileReader reader = new FileReader("aa.txt");
        //read
        char[] chars = new char[1024];
        int readCount = reader.read(chars);
        System.out.println(new String(chars,0,readCount));
        // close
        reader.close();
    }
}

缓冲流BufferedReader

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取

继承关系

在这里插入图片描述

构造方法

BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。

成员方法

3个read方法 + readLine()

StringreadLine() 读取一个文本行。
注意包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
package com.cskaoyan.charstream;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * @description: BufferedReader
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo6 {
    public static void main(String[] args) throws IOException {
        // 创建输入流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        // read方法读取数据
        //int readData = br.read();
        //System.out.println(((char) readData));
        // readLine
        //read1(br);
        //循环读
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        // close
        br.close();
    }

    private static void read1(BufferedReader br) throws IOException {
        String s = br.readLine();
        System.out.println(s);
    }
}

用字符流去复制文件

文本文件

package com.cskaoyan.charstream;

import java.io.*;

/**
 * @description: 复制文件
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo7 {
    public static void main(String[] args) throws IOException {
        // 创建输入流对象
        InputStreamReader inputStreamReader =
                new InputStreamReader(new FileInputStream("a.txt"));
        // 创建输出流对象
        OutputStreamWriter out =
                new OutputStreamWriter(new FileOutputStream("b.txt"));
        // 边读边写
        int readData;
        while ((readData = inputStreamReader.read()) != -1) {
            out.write(readData);
        }
        //close
        inputStreamReader.close();
        out.close();
    }
}


非文本文件

package com.cskaoyan.charstream;

import java.io.*;

/**
 * @description: 复制文件
 * @author: songtao@cskaoyan.onaliyun.com
 **/

// 不能成功复制
public class Demo8 {
    public static void main(String[] args) throws IOException {
        // 创建输入流对象
        InputStreamReader inputStreamReader =
                new InputStreamReader(new FileInputStream("D:\\mm.jpg"));
        // 创建输出流对象
        OutputStreamWriter out =
                new OutputStreamWriter(new FileOutputStream("copy_mm.jpg"));
        // 边读边写
        int readData;
        while ((readData = inputStreamReader.read()) != -1) {
            out.write(readData);
        }
        //close
        inputStreamReader.close();
        out.close();
    }
}

其他流(了解)

数据流

练习:

向文件当中写入1000 , 3.14 看一下能否成功?

不能写入

DataInputStream

数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型

构造方法:

DataInputStream(InputStream in)

成员方法:

每一个java基本数据类型都有1个read方法与之对应 比如 读取int readInt()

package com.cskaoyan.otherstream;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @description:
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo3 {
    public static void main(String[] args) throws IOException {
        // 读取java中的数据类型
        DataInputStream in = new DataInputStream(new FileInputStream("b.txt"));
        // read
        // readInt()
        int i = in.readInt();
        System.out.println(i);
        // readDouble()
        double v = in.readDouble();
        System.out.println(v);
        // readBoolean
        boolean b = in.readBoolean();
        System.out.println(b);
        in.close();
    }
}

DataOutputStream

数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

构造方法

DataOutputStream(OutputStream out) 创建一个新的数据输出流,将数据写入指定基础输出流。

成员方法:

每一种java基本数据类型都有1个write方法与之对应 比如 写入int方法 writeInt(int i)

package com.cskaoyan.otherstream;

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @description:
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo2 {
    public static void main(String[] args) throws IOException {
        // 创建数据输出流对象
        DataOutputStream out = new DataOutputStream(new FileOutputStream("b.txt"));
        // 用不同的类型的write方法写数据
        // 写1000 writeInt(int v)
        out.writeInt(1000);
        // 写3.14
        out.writeDouble(3.14);
        // true
        out.writeBoolean(true);
        // close
        out.close();
    }
}

package com.cskaoyan.otherstream;

import java.io.*;

/**
 * @description:
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo4 {
    public static void main(String[] args) throws IOException {
        write();
        read();
    }

    private static void read() throws FileNotFoundException, IOException {
        DataInputStream dis = new DataInputStream(
                new FileInputStream("dos.txt"));
        byte b = dis.readByte();
        System.out.println(b);
        short s = dis.readShort();
        System.out.println(s);
        int i = dis.readInt();
        System.out.println(i);
        long l = dis.readLong();
        System.out.println(l);
        float f = dis.readFloat();
        System.out.println(f);
        double d = dis.readDouble();
        System.out.println(d);
        char ch = dis.readChar();
        System.out.println(ch);
        boolean bb = dis.readBoolean();
        System.out.println(bb);
        dis.close();
    }

    private static void write() throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                "dos.txt"));
        dos.writeByte(1);
        dos.writeShort(20);
        dos.writeInt(300);
        dos.writeLong(4000);
        dos.writeFloat(12.34f);
        dos.writeDouble(12.56);
        dos.writeChar('a');
        dos.writeBoolean(true);
        dos.close();
    }

}

注意:

按照什么样的方式去写 那么就要按照相同的方式去读取

在这里插入图片描述

打印流

打印流的核心思想

把不同的数据类型都转换成了字符串 写的就是字符串

练习:

定义一个类 Printer

4个方法

printInt(int i) 写int类型的数据

printIntLn(int i) 写int类型的数据 在加上换行

printDouble(double d) 写double类型的额数据到文件

printDoubleLn(double d) 写double类型的数据 再换行

package com.cskaoyan.otherstream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @description: print思想
 * @author: songtao@cskaoyan.onaliyun.com
 **/

/*
定义一个类 Printer

4个方法

 printInt(int i)    写int类型的数据

 printIntLn(int i)  写int类型的数据 在加上换行

printDouble(double d) 写double类型的额数据到文件

printDoubleLn(double d) 写double类型的数据  再换行
 */
public class Demo5 {
    public static void main(String[] args) throws IOException{
        Printer printer = new Printer(new FileOutputStream("a.txt"));
        // 写入int 1000
        printer.printIntLn(1000);
        printer.printDouble(3.14);
        // close
        printer.close();
    }
}

class Printer{
    // 定义一个成员变量
    OutputStream outputStream;

    public Printer(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    // 成员方法
    public void printInt(int a) throws IOException {
        // int  转字符串
        String s = String.valueOf(a);
        // 利用out去写入数据到文件当中
        outputStream.write(s.getBytes());
    }

    public void printIntLn(int a) throws IOException {
        String s = String.valueOf(a);
        outputStream.write(s.getBytes());
        // 再写入一个换行符
        outputStream.write(System.lineSeparator().getBytes());
    }

    public void printDouble(double d) throws IOException {
        // double →  字符串
        String s = String.valueOf(d);
        // write
        outputStream.write(s.getBytes());
    }

    public void printDoubleLn(double d) throws IOException {
        // double →  字符串
        String s = String.valueOf(d);
        // write
        outputStream.write(s.getBytes());
        // 换行符
        outputStream.write(System.lineSeparator().getBytes());
    }
    public void close() throws IOException {
        outputStream.close();
    }


}

字节打印流PrintStream

PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式

继承关系

在这里插入图片描述

构造方法:

PrintStream(File file) 创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(OutputStream out) 创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush)

PrintStream(String fileName) 创建具有指定文件名称且不带自动行刷新的新打印流。

成员方法:

每个java数据类型都有一个print方法

package com.cskaoyan.otherstream;

import java.io.IOException;
import java.io.PrintStream;

/**
 * @description: PrintStream
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo6 {
    public static void main(String[] args) throws IOException {
        // 创建字节打印流对象
        PrintStream printStream = new PrintStream("a.txt");
        // 向文件中写数据  利用相应的print方法
        printStream.println(1000);
        // close
        printStream.close();
    }
}

字符打印流PrintWriter

向文本输出流打印对象的格式化表示形式

继承关系

在这里插入图片描述

构造方法

PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out) 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter。
PrintWriter(String fileName) 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
PrintWriter(Writer out) 创建不带自动行刷新的新 PrintWriter。
PrintWriter(Writer out, boolean autoFlush) 创建新 PrintWriter。

成员方法:

各种print方法

打印流的4个特点

  • 只能操作目的地,不能操作数据来源
    • 没有相应的输入流与之对应
  • 可以操作任意类型的数据
    • 原理就是把不同类型转化为了字符串去处理
  • 如果启动了自动刷新功能 就会自动刷新
    • 如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区

    • 为什么能够自动刷新

    • 在这里插入图片描述

    • 在这里插入图片描述

    • 在这里插入图片描述

    • 传的参数可以是文件对象 文件名

标准输入输出流

System.out

  • 标准输出流
  • 默认的输出设备 显示器
  • 本质是一个字节打印流

System.in

  • 标准输入流
  • 默认的输入设备 键盘
  • 本质是一个普通的字节输入流

练习:

利用System.in 以及 BufferedReader 模拟 Scanner 当中的nextLine方法

package com.cskaoyan.otherstream;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @description: 模拟scanner
 * @author: songtao@cskaoyan.onaliyun.com
 **/

/*
利用System.in  以及 BufferedReader 模拟  Scanner 当中的nextLine方法
 */
public class Demo9 {
    public static void main(String[] args) throws IOException {
        // 创建一个BufferedReader对象
        // 问题:我们需要一个Reader 字符输入流作为参数
        // 能用的就是System.in  本质是一个普通的字节输入流InputStream
        // 思路:字节流 字符流的桥梁就是转换流
        BufferedReader br =
                new BufferedReader(new InputStreamReader(System.in));
        // 就可以利用readLine方法了
        //read1(br);

        // 可以重复输入   当输入值为"gun" 结束循环
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
            // 约定1个结束标记 作为结束符
            if (line.equals("gun")) {
                break;
            }
        }

        // close
        br.close();
    }

    private static void read1(BufferedReader br) throws IOException {
        String s = br.readLine();
        System.out.println(s);
    }
}

对象流(序列化流 反序列化流)

序列化:

把对象数据转为为二进制数据 持久化存储的过程

反序列化:

把二进制数据还原为对象数据的过程

Student s = new Student("zs",20)

序列化流ObjectOutputStream

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream

继承关系

在这里插入图片描述

构造方法:

ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。

成员方法:

voidwriteObject(Object obj) 将指定的对象写入 ObjectOutputStream。
package com.cskaoyan.otherstream;

import java.io.*;

/**
 * @description: 序列化
 * @author: songtao@cskaoyan.onaliyun.com
 **/

public class Demo10 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 把学生对象信息写入文件
        serialize();
        // 反序列化
        // 创建一个反序列流对象
        ObjectInputStream in =
                new ObjectInputStream(new FileInputStream("aa.txt"));
        // readObject方法
        Student student = (Student) in.readObject();
        System.out.println(student);
        // close
        in.close();
    }

    private static void serialize() throws IOException {
        // 创建一个学生对象
        Student student = new Student("张三", 20,99);
        // 创建序列化流对象
        ObjectOutputStream out =
                new ObjectOutputStream(new FileOutputStream("aa.txt"));
        // writeObject(Object obj) 写入对象信息
        out.writeObject(student);
        // close
        out.close();
    }
}

class Student implements Serializable {
    // 定义成员变量
    String name;
    int age;
    boolean gender;
    // serialVersionUID  名字要一致
    static final long serialVersionUID = -2898402714175754521l;

    // 添加1个分数
    transient int score;

    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", score=" + score +
                '}';
    }
}

注意:

  • 要想实习序列化功能 必须要实现Serializable接口
  • Serializable接口 是一个空接口 起到一个标记的作用
  • 如果在Student类中添加1个成员变量 还能否正常读取
    • 要使得2个serialVersionUID保持一致
  • 如果类中成员变量信息 不想被序列化 这时候 使用关键字 transient

异常:

  • java.io.NotSerializableException 没有实现Serializable接口
  • java.io.InvalidClassException: com.cskaoyan.otherstream.Student; local class incompatible: stream classdesc serialVersionUID = -2898402714175754521, local class serialVersionUID = -1896616544424779089 类中的信息发生改变

反序列化流ObjectInputStream

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化

继承关系

在这里插入图片描述

构造方法

ObjectInputStream(InputStream in)

成员方法:

readObject()

总结

类型字节输出流字节输入流字符输出流字符输入流
基类OutputStreamInputStreamWriterReader
文件相关FileOutputStreamFileInputStreamFileWriterFileReader
缓冲流BufferedOutputStreamBufferedInputStreamBufferedWriterBufferedReader
转换流OutputStreamWriterInputStreamReader
数据流DataOutputStreamDataInputStream
打印流PrintStreamPrintWriter
对象流ObjectOutputStreamObjectInputStream

作业

1.利用字符流去读取一个文本文件,每次读取一行,并将这行数据逆序,写入新的文本文件当中

public class Demo01 {
    public static void main(String[] args) throws IOException {
        // 创建一个输入流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        String line;
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
        // 每次接收一行存为字符串,当文本中没有数据之后,得到的是null
        while((line = br.readLine()) != null){
            System.out.println(line);
            char[] chars = line.toCharArray();
            for (int i = chars.length - 1; i >= 0; i--) {
                bw.write(chars[i]);
            }
            bw.newLine();
        }
        br.close();
        bw.close();
    }
}

2.准备一个文本文件,其中包含英文 ,数字, 中文字符。
设计一个方法

public static void encodeFile(File encodingFile, File encodedFile);

在这个方法中把encodingFile的内容进行加密,然后保存到encodedFile文件中。

加密算法:
数字:
如果不是9的数字,在原来的基础上加1,比如5变成6, 3变成4
如果是9的数字,变成0
字母字符:
如果是非z字符,向右移动一个,比如d变成e, G变成H
如果是z,z->a, Z-A。
字符需要保留大小写
非字母字符
比如',&^ 保留不变,中文也保留不变
public class Demo02 {
    public static void main(String[] args) throws IOException {
        File encodingFile = new File("/Users/chelsea-he/Documents/JAVA33th/testFile/encodingFile.txt");
        File encodedFile = new File("/Users/chelsea-he/Documents/JAVA33th/testFile/encodedFile.txt");
        encodeFile(encodingFile, encodedFile);
    }

    public static void encodeFile(File encodingFile, File encodedFile) throws IOException, NullPointerException{
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
             br = new BufferedReader(new FileReader(encodingFile));
             bw = new BufferedWriter(new FileWriter(encodedFile));
            String line;
            while((line = br.readLine()) != null){
                char[] chars = line.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    if(chars[i] >= 'a' && chars[i] <= 'z'){
                        if(chars[i] == 'z') chars[i] = 'a';
                        else chars[i] = (char)(chars[i] + 1);
                    }
                    if(chars[i] >= 'A' && chars[i] <= 'Z'){
                        if(chars[i] == 'Z') chars[i] = 'A';
                        else chars[i] = (char)(chars[i] + 1);
                    }
                    if(chars[i] >= '1' && chars[i] <= '9'){
                        if(chars[i] == '9') chars[i] = '0';
                        else chars[i] = (char)(chars[i] + '1');
                    }
                }
                bw.write(chars);
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }



    }
}

3.解密在文件加密中生成的文件(解密刚才加密的文件)。
设计一个方法

public static void decodeFile(File decodingFile, File decodedFile);

在这个方法中把decodingFile的内容进行解密,然后保存到decodedFile文件中。

解密算法:
数字:
如果不是0的数字,在原来的基础上减1,比如6变成5, 4变成3
如果是0的数字,变成9
字母字符:
如果是非a字符,向左移动一个,比如e变成d, H变成G
如果是a,a->z, A-Z。
字符需要保留大小写
非字母字符:
比如',&^ 保留不变,中文也保留不变
public class Demo02 {
    public static void main(String[] args) throws IOException {
        File encodingFile = new File("/Users/chelsea-he/Documents/JAVA33th/testFile/encodingFile.txt");
        File encodedFile = new File("/Users/chelsea-he/Documents/JAVA33th/testFile/encodedFile.txt");
        File decodedFile = new File("/Users/chelsea-he/Documents/JAVA33th/testFile/decodedFile.txt");
        // encodeFile(encodingFile, encodedFile);
        decodeFile(encodedFile, decodedFile);
    }


    public static void decodeFile(File encodedFile, File decodedFile){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try{
            br = new BufferedReader(new FileReader(encodedFile));
            bw = new BufferedWriter(new FileWriter(decodedFile));
            String line;
            while((line = br.readLine()) != null){
                char[] chars = line.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    if(chars[i] >= 'a' && chars[i] <= 'z'){
                        if(chars[i] == 'a') chars[i] = 'z';
                        else chars[i] = (char)(chars[i] - 1);
                    }
                    if(chars[i] >= 'A' && chars[i] <= 'Z'){
                        if(chars[i] == 'A') chars[i] = 'Z';
                        else chars[i] = (char)(chars[i] - 1);
                    }
                    if(chars[i] >= '1' && chars[i] <= '9'){
                        if(chars[i] == '0') chars[i] = '9';
                        else chars[i] = (char)(chars[i] - 1);
                    }
                }
                bw.write(chars);
                bw.newLine();
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值