IO流..

1. File类

1.1 File类的创建

  1. new File(String pathName) 根据路径构建一个File对象
  2. new File(File parent,String child) 根据父目录文件+子路径构建
  3. new File(String parent,String child) 根据父目录+子路径构建
public class FileTest {
    
    
    @Test
    public void fileCreat() throws IOException {
    
    
        // new File(String pathName) 根据路径构建一个File对象
        File file = new File("D:\\java学习资源\\file1.txt");
        boolean flag = file.createNewFile();
        if (flag) {
    
    
            System.out.println("file文件创建成功");
        }
        // new File(File parent,String child) 根据父目录文件+子路径构建
        File parent = new File("D:\\java学习资源\\");
        File file1 = new File(parent, "file2.txt");
        boolean flag2 = file1.createNewFile();
        if (flag2) {
    
    
            System.out.println("file2文件创建成功");
        }
        // new File(String parent,String child) 根据父目录+子路径构建
        File file2 = new File("D:\\java学习资源\\", "file3.txt");
        boolean flag3 = file2.createNewFile();
        if (flag3) {
    
    
            System.out.println("file3文件创建成功");
        }

    }

}

1.2 获取文件的信息

public class GetFileInformation {
    
    
    @Test
    public void getFileInformation(){
    
    
        File file = new File("D:\\java学习资源\\file1.txt");
        System.out.println("文件名是"+file.getName());
        System.out.println("文件路径是"+file.getAbsolutePath());
        System.out.println("文件大小是(按照字节进行计算)"+file.length());
        System.out.println("文件的父级目录"+file.getParent());
        System.out.println("文件是否存在"+file.exists());
        System.out.println("是不是一个文件"+file.isFile());
        System.out.println("是不是一个目录"+file.isDirectory());
    }
}

1.3 目录操作和文件删除

public class FileDirectoryAndDelete {
    
    
    public static void main(String[] args) throws IOException {
    
    
        File file = new File("D:\\java学习资源\\file1.txt");
        // 判断D:\java学习资源\file1.txt是否存在,如果存在就删除
        boolean flag = file.exists();
        if (flag){
    
    
            boolean delete = file.delete();
            if (delete){
    
    
                System.out.println("删除成功");
            }
        }else {
    
    
            System.out.println("文件不存在");
        }

        // 创建目录,mkdir创建一级目录,mkdirs创建多级目录
        File file2 = new File("D:\\java学习资源\\test\\test\\test");
        boolean flag2 = file2.mkdirs();
        if (flag2){
    
    
            System.out.println("目录创建成功");
        }

        // deleteOnExit文档解释为:在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。也就是说,程序运行deleteOnExit成功后,File并没有直接删除,而是在虚拟机正常运行结束后才会删除。 
        File file3 = new File("D:\\java学习资源\\file3.txt");
        file3.createNewFile();
        file3.deleteOnExit();
    }
}

delete和deleteOnExit方法的区别

  1. delete为直接删除
  2. deleteOnExit文档解释为:在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。也就是说,程序运行deleteOnExit成功后,File并没有直接删除,而是在虚拟机正常运行结束后才会删除。

2. IO

流的分类

  1. 按操作数据单位分类:字节流(8bit),字符流(按字符)
  2. 按数据流的流向分类:输入流,输出流
  3. 按流的角色分类:节点流,处理流/包装流

请添加图片描述

请添加图片描述

字节流:在操作二进制文件(音频)使用字节流能保证无损
字符流:用于操作文本文件更好

流和文件的关系

2.1 InputStream

2.1.1 FileInputStream

   public void FileInputStreamTest() throws IOException {
    
    
        // 使用流将D:\java学习资源\file.txt文件的内容输出到控制台
        File file = new File("D:\\java学习资源\\file.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        int byte_ = 0;
        while (byte_ != -1) {
    
    
            byte_ = fileInputStream.read();
            System.out.print((char) byte_);
        }
        fileInputStream.close();
    }

请添加图片描述
乱码的原因是因为在UTF-8中一个汉字占用三个字节,但是read方法是一个字节进行读取,所以在读取的时候获取到的数据在进行char转换后会出现乱码。

解决方法

public void FileInputStreamTest() throws IOException {
    
    
        // 使用流将D:\java学习资源\file.txt文件的内容输出到控制台
        File file = new File("D:\\java学习资源\\file.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        int length = 0;
        byte[] bytes = new byte[3];
        while ((length = (fileInputStream.read(bytes))) != -1) {
    
    
            System.out.print(new String(bytes, 0, length));
        }
        fileInputStream.close();
    }

2.2 OutputStream

2.2.1 FileOutputStream

将内容写入到文件

 @Test
    public void FileOutputStreamTest() throws IOException {
    
    
        File file = new File("D:\\java学习资源\\file2.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        String text = "小宝宝";
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        // 将字节数组写入到文件
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }

上述方式,当写入内容时会覆盖原来的内容。如何使用追加进行写入?

   public void FileOutputStreamTest() throws IOException {
    
    
        File file = new File("D:\\java学习资源\\file2.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file,true);
        String text = "小宝宝";
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        // 将字节数组写入到文件
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }

使用构造器创建FileOutputStream对象时添加一个boolean属性,true为追加内容,false为覆盖内容,默认为false
请添加图片描述

2.3 文件的拷贝

  1. 获取输入流
  2. 输出流输出内容
 public void copy() throws IOException {
    
    
        // 将D:\java学习资源\书籍\Spring源码深度解析@www.java1234.com.pdf拷贝一份到d盘
        // 创建输入流,将文件读入到程序
        File input = new File("D:\\java学习资源\\书籍\\Spring源码深度解析@www.java1234.com.pdf");
        FileInputStream fileInputStream = new FileInputStream(input);

        File output = new File("D:\\Spring源码深度解析@www.java1234.com.pdf");
        FileOutputStream fileOutputStream = new FileOutputStream(output);

        byte[] inputByte = new byte[1024];
        int len = 0;
        while (true) {
    
    
            len = fileInputStream.read(inputByte);
            if (len == -1) {
    
    
                break;
            }
            fileOutputStream.write(inputByte, 0, len);
        }
        fileInputStream.close();
        fileOutputStream.close();
    }

2.4 Reader

2.5.1 FileReader

获取文件内容并在控制台显示

 public void FileReaderTest() throws IOException {
    
    
        FileReader fileReader = new FileReader("D:\\java学习资源\\file2.txt");
        //方式1
        int read = 0;
        while (true) {
    
    
            read = fileReader.read();
            if (read == -1) {
    
    
                break;
            }
            System.out.print((char) read);
        }
        //方式2
        char[] input = new char[1024];
        int len = 0;
        while (true) {
    
    
            len = fileReader.read(input);
            if (len == -1) {
    
    
                break;
            }
            System.out.println(new String(input,0,len));
        }
    }

2.5 Writer

2.5.1 FileWriter

注意,在FileWriter使用后必须关闭(close)或者刷新(flush),否则不能将内容写入到指定文件

 public void FileWriterTest() throws IOException{
    
    
        File file = new File("D:\\java学习资源\\file2.txt");
        FileWriter fileWriter = new FileWriter(file,true);
        String s  = new String("哦买嘎");
        char[] chars = new char[5];
        s.getChars(0,s.length(),chars,0);
        fileWriter.write(chars,0,s.length());
        fileWriter.close();
    }

2.6 节点流和处理流

  1. 节点流可以从一个特定的数据源读写数据,如FileReader,FIleWriter
  2. 处理流(包装流)是 “连接” 在已存在的流(节点流或处理流)之上,为程序提高更强大的读写功能,如BufferedReader,BufferedWriter
  3. 处理流对节点流进行包装,使用了装饰器模式,不会直接与数据源相连

请添加图片描述

2.6.1 模拟装饰器实现处理流

  1. 抽象类,节点流的父类
public abstract class Reader_ {
    
    
    public void readFile(){
    
    }
    public void readString(){
    
    }
}
  1. 节点流FileReader
public class FileReader_ extends Reader_{
    
    
    public void readFile(){
    
    
        System.out.println("读取文件");
    }
}
  1. 节点流StringReader
public class StringReader_ extends Reader_{
    
    
    public void readString(){
    
    
        System.out.println("读取字符串");
    }
}
  1. 处理流
public class BufferedReader_ extends Reader_ {
    
    
    private Reader_ reader; // 属性是Reader_

    public BufferedReader_(Reader_ reader){
    
    
        this.reader = reader;
    }

    // 让方法更灵活,多次读取文件
    public void readFile(int num) {
    
    
        for (int i =0;i<num;i++){
    
    
            reader.readFile();
        }
    }

    // 让方法更灵活,多次读取字符串
    public void readString(int num) {
    
    
        for (int i =0;i<num;i++){
    
    
            reader.readString();
        }
    }
}

5.测试

public class Test {
    
    
    public static void main(String[] args) {
    
    
        BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
        bufferedReader_.readFile(2);
    }
}

请添加图片描述

2.6.2 BufferedReader

关闭流时只需要关闭外层流即可

  public void BufferedReaderTest() throws IOException {
    
    
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\java学习资源\\file2.txt"));
        char[] chars = new char[5];
        int len = 0;
        while (true){
    
    
            len = bufferedReader.read(chars);
            if (len==-1){
    
    
                break;
            }
            System.out.print(new String(chars,0,len));
        }
        bufferedReader.close();

        // 方法2
        BufferedReader bufferedReader2 = new BufferedReader(new FileReader("D:\\java学习资源\\file2.txt"));
        String s = null;
        while (true){
    
    
            s = bufferedReader2.readLine();
            if (null == s){
    
    
                break;
            }
            System.out.println(s);
        }
        bufferedReader2.close();
    }

2.6.3 BufferedWriter

往文件内追加内容

 public void BufferedWriterTest() throws IOException{
    
    
        // 将贵州彭于晏追加到D:\\java学习资源\\file2.txt"
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\java学习资源\\file2.txt",true));
        String s = new String("贵州彭于晏");
        char[] output = s.toCharArray();
        bufferedWriter.write(output);
        // 建议插入一个换行符
        bufferedWriter.write('\n');
        // 这也是换行符,插入一个与系统相关的换行符
//        bufferedWriter.newLine();
        bufferedWriter.close();
    }

2.6.4 文件拷贝

拷贝pdf,选择字节流

 public void BufferedCopy() throws IOException{
    
    
        // 将D:\java学习资源\书籍\Spring源码深度解析@www.java1234.com.pdf拷贝一份到d盘
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\\java学习资源\\书籍\\Spring源码深度解析@www.java1234.com.pdf"));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\我的Spring源码深度解析.pdf"));
        byte[] chars = new byte[1024];
        int len = 0;
        while(true){
    
    
            len = bufferedInputStream.read(chars);
            if (len == -1){
    
    
                break;
            }
            bufferedOutputStream.write(chars,0,len);
//            bufferedOutputStream.flush();
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();
    }

2.6.5 ObjectInputStream/ObjectOutputStream

需求:

  1. 将int num = 100保存到文件中,注意不是数字100,而是int 100,并且能够从文件中直接恢复int 100
  2. 将Dog dog = new Dog(“小黄”,3) 这个对象保存到文件中,并且能从文件中恢复

这里涉及到了序列化和反序列化

  1. 序列化就是在保存数据时,就是保存数据的值和数据类型
  2. 反序列化就是恢复数据时,恢复数据的值和数据类型
  3. 实现Serializable或者Externalizable即可支持序列化机制 ,推荐Serializable
 public void ObjectInputOutputStreamTest() throws IOException, ClassNotFoundException {
    
    
        // ObjectOutputStream序列化基本数据类型和Dog对象并保存到data.bat文件中
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\data.dat"));
        Dog dog = new Dog("jxj");
        // 序列化int数据,int会自动装箱为Integer对象,Integer对象实现了Serializable
        objectOutputStream.writeInt(100);
        objectOutputStream.writeBoolean(true);
        objectOutputStream.writeChar('张');
        objectOutputStream.writeDouble(9.50);
        objectOutputStream.writeUTF("你好,世界");
        objectOutputStream.writeObject(dog);
        objectOutputStream.close();
        System.out.println("序列化完毕");

        // 反序列化
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\data.dat"));
        // 读取的顺序一定要和存放的顺序一致
        Integer i = (Integer) objectInputStream.readInt();
        System.out.println(i);
        System.out.println(objectInputStream.readBoolean());
        System.out.println(objectInputStream.readChar());
        System.out.println(objectInputStream.readDouble());
        System.out.println(objectInputStream.readUTF());
        System.out.println(objectInputStream.readObject().getClass());
        objectInputStream.close();

    }

注意:

  1. 读写顺序一致
  2. 要求实现序列化或反序列化对象,需要实现Serializable
  3. 序列化的类中建议添加SerialVersionUID
  4. 序列化对象时,默认将所有属性序列化,除了static和transient修饰的成员
  5. 序列化对象时,要求里面的属性的类型也需要实现序列化接口
  6. 序列化具备可继承性

2.6.6 转换流InputStreamReader/OutputStreamWriter

如何把字节流转换为字符流呢?使用转换流

文件乱码问题,读取一个gbk编码的文件

   public void CodeQuestion() throws IOException{
    
    
        // 中文乱码问题
        // 读取"D:\java学习资源\file2.txt"文件
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\java学习资源\\file3txt.txt"));
        char[] chars = new char[5];
        int len = 0;
        while(true){
    
    
            len = bufferedReader.read(chars);
            if (len==-1){
    
    
                break;
            }
            System.out.println(new String(chars,0,len));
        }
        bufferedReader.close();
    }

请添加图片描述

 @Test
    public void inputStreamReaderTest() throws IOException {
    
    
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\java学习资源\\a.txt"), "gbk");
        char[] chars = new char[5];
        int len = 0;
        while (true) {
    
    
            len = inputStreamReader.read(chars);
            if (len == -1) {
    
    
                break;
            }
            System.out.println(new String(chars, 0, len));
        }
        inputStreamReader.close();
    }

    @Test
    public void outputStreamWriterTest() throws IOException{
    
    
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\java学习资源\\a.txt"),"gbk");
        String s = "贵州彭于晏哟哟哟哟";
        char[] chars = s.toCharArray();
        outputStreamWriter.write(chars);
        outputStreamWriter.close();
    }

2.6.7 打印流PrintStream/PrintWriter

打印流只有输出流,没有输入流

2.6.8 properties

需求:如下所示一个配置文件mysql.properties
ip=192.168.0.13
user=root
password=zjh
请读取三个字段的值

 @Test
    public void propertiesTest() throws IOException{
    
    
        Properties properties = new Properties();
        properties.load(new FileReader("D:\\java学习资源\\mysql.properties"));
        properties.list(System.out);
        String ip = properties.getProperty("ip");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        System.out.println(ip+" "+username+" "+password);
    }

猜你喜欢

转载自blog.csdn.net/weixin_45690465/article/details/124313768