Java基础IO流 韩顺平Java笔记

文件

文件的概念

文件是保存数据的地方,比如word文档,txt文件,excel文件,都是文件。它能保存图片、视频、声音……

文件流

文件在程序中时以流的形式来操作的
文件流

流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径

常用的文件操作

创建文件对象相关构造器和方法

相关方法
new File(String pathname) //根据路径构建一个File对象
new File(File parent,String child) //根据父目录文件+子路径构建
new File(String parent, String child) //根据父目录+子路径构建
createNewFile 创建新文件

类图:比较和串行化
比较和串行化


获取文件信息

获取文件的相关信息
  getName:获取文件名     
  getAbsolutePath:获取绝对路径   
  getParent:获取文件的上级目录  
  length:文件大小(返回字节)   
  exists:文件是否存在   
  isFile:是否是文件  
  isDirectory:是不是一个文件目录

代码示例:

package com.FilementOperation;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

/**
 * @author wty
 * @date 2022/9/28 21:18
 */
public class FileInfomation {
    // 获取文件信息
    @Test
    public void info() {
        // 先创建对象
        File file = new File("E:\\news1.txt");
/*        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        System.out.println(file.getName());
        /**
         * getName:获取文件名
         * getAbsolutePath:获取绝对路径
         * getParent:获取文件的上级目录
         * length:文件大小(返回字节)
         * exists:文件是否存在
         * isFile:是否是文件
         * isDirectory:是不是一个文件目录
         */
        System.out.println(file.getAbsoluteFile());
        System.out.println(file.getParent());
        System.out.println(file.length());
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
    }
}

常用的文件操作

目录的操作和文件删除

mkdir创建一级目录、mkdirs创建多级目录、delete只能删除空目录或者文件

示例:

package com.Directorys;

import java.io.File;

/**
 * @author wty
 * @date 2022/9/28 21:34
 */
public class Directories {
    public static void main(String[] args) {
        //m1();
        //m2();
        m3();
        m4();
    }

    // 判断E盘是否存在news1.txt,有的话就删除
    public static void m1() {
        File file = new File("E:\\news1.txt");
        if (file.exists()) {
            if (file.delete()) {// 返回:布尔值
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }

        } else {
            System.out.println("文件不存在!");
        }

    }

    // 判断E盘目录是否存在news1.txt,有的话就删除
    // JAVA中目录也是一种文件
    public static void m2() {
        File file = new File("E:\\news1");
        if (file.isDirectory()) {
            if (file.delete()) {// 返回:布尔值
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }

        } else {
            System.out.println("目录不存在!");
        }

    }

    // 判断E盘目录是否存在news3,不存在的话就创建一个
    public static void m3() {
        File file = new File("E:\\news3");
        if (file.exists()) {
            System.out.println("文件已存在!");
        } else {
            if (file.mkdir()) { // 创建一级目录
                System.out.println("文件创建成功!");
            } else {
                System.out.println("文件创建失败!");
            }
        }
    }

    // 判断E盘目录是否存在E:\\1\\news3,不存在的话就创建一个
    public static void m4() {
        File file = new File("E:\\1\\news3");
        if (file.exists()) {
            System.out.println("文件已存在!");
        } else {
            if (file.mkdirs()) { // 创建多级目录
                System.out.println("文件创建成功!");
            } else {
                System.out.println("文件创建失败!");
            }
        }
    }
}

IO流原理和分类

JAVA IO流原理

  1. I/O 流是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。
  2. JAVA程序中,对于数据的输入/输出操作以"流"(Stream)的方式进行。
  3. Java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过方法输入或输出数据。
  4. 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  5. 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

流的分类

按照操作数据单位的不同分为:字节流(二进制文件:声音、视频、word文件无损操作)、字符流(效率高,文本文件)。
按照数据流的流向不同分为:输入流、输出流。
按流的角色的不同分为:节点流、处理流/包装流。

抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

(1)Java的IO流共涉及40多个类,实际上非常规则,都是从以上4个抽象基类派生的。
(2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

Java的IO流


代码示例:

public class Stream {
    // 1.四个都是抽象类,不能够实例化,也只能实例化对应的子类对象才能操作

    //OutputStream;
    //InputStream;
    //Reader;
   // Writer;
}

InputStream:字节输入流

InputStream抽象类是所有类字节输入流的超类
InputStream常用的子类

1.FileInputStream:文件输入流

package com.InputStream;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author wty
 * @date 2022/9/29 0:08
 */
public class FileInputSteamUse {
    public static void main(String[] args) {

    }

    /**
     * 演示读取文件
     * 单个字节的读取,效率很低
     * read()
     */
    @SuppressWarnings({"all"})
    @Test
    public void readFilement() {
        int readData = 0;
        FileInputStream fileInputStream = null;
        try {
            // 创建FileInputStream对象,用来读取文件
            fileInputStream = new FileInputStream("E:\\hello.txt");
            // 如果返回-1,表示读取完毕
            while ((readData = fileInputStream.read()) != -1) {// 返回int
                System.out.print((char) readData);
            }
            System.out.println();
            System.out.println("文件读取完毕!");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 文件流一定要关闭
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 演示读取文件
     * 字节数组的读取,效率比上面稍微高一些
     * read(byte[] b) 优化
     */
    @SuppressWarnings({"all"})
    @Test
    public void readFilementYh() {
        int readData = 0;
        byte[] bytes = new byte[8]; // 一次读取8个字节
        FileInputStream fileInputStream = null;
        try {
            // 创建FileInputStream对象,用来读取文件
            fileInputStream = new FileInputStream("E:\\hello.txt");
            // 如果正常的话,返回的是实际读取的字节数
            // 如果返回-1,表示读取完毕
            while ((readData = fileInputStream.read(bytes)) != -1) {// 返回int
                System.out.print(new String(bytes, 0, readData));
            }
            System.out.println();
            System.out.println("文件读取完毕!");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 文件流一定要关闭
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.BufferedInputStream:缓冲字节输入流

3.ObjectInputStream:对象字节输入流

OutputStream:字节输出流

1.FileOuputStream

FileOuputStream类图

package com.OutputStream;
	
	import org.junit.Test;
	
	import java.io.FileOutputStream;
	import java.io.IOException;
	import java.io.OutputStream;
	import java.nio.charset.StandardCharsets;
	
	/**
	 * @author wty
	 * @date 2022/9/29 0:46
	 */
	public class FileOutputSteamOperation {
	    @SuppressWarnings({"all"})
	    @Test
	    public void writeFilement() {
	        char a = 'h'; // char和int可以相互转换
	        // 创建FileOutputStream对象
	        FileOutputStream fileOutputStream = null;
	        try {
	            fileOutputStream = new FileOutputStream("E:\\a.txt");
	            fileOutputStream.write(a);
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                fileOutputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	
	    @SuppressWarnings({"all"})
	    @Test
	    public void writeFilementYh() {
	        String str = "hello,world";
	        // 创建FileOutputStream对象
	        FileOutputStream fileOutputStream = null;
	        try {
	            fileOutputStream = new FileOutputStream("E:\\a.txt");
	            fileOutputStream.write(str.getBytes()); // 字符串转换成byte数组
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                fileOutputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	
	    @SuppressWarnings({"all"})
	    @Test
	    public void writeFilementYhlength() {
	        String str = " hello.";
	        // 创建FileOutputStream对象
	        FileOutputStream fileOutputStream = null;
	        try {
	            // 多次写入内容是覆盖
	            //fileOutputStream = new FileOutputStream("E:\\a.txt");
	            // 多次写入是追加到文件后面
	            //  fileOutputStream = new FileOutputStream(filePath,true);
	            fileOutputStream = new FileOutputStream("E:\\a.txt", true);
	
	            fileOutputStream.write(str.getBytes(), 0, str.length()); // 字符串偏移量(截取其中几个字符写入)
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                fileOutputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	}

2.BufferedOutputStream:缓冲字节输出流

3.ObjectOutputStream:对象字节输出流

文件的拷贝


package com.FileCopy;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author wty
 * @date 2022/9/30 17:32
 */
public class FileCopy {
    @Test
    @SuppressWarnings({"all"})
    public void copyDocument() {
        // 将E:\1\1.jpg 拷贝到 E:\2\1.jpg
        // 思路分析:1.创建文件输入流 将文件读入到程序
        // 2.创建文件的输出流 将读取到的文件数据写入到指定的位置
        // 特别注意:循环读取,读取部分就写入指定位置(以防文件很大读取很慢)
        String path = "E:\\1\\1.jpg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        byte[] bytes = new byte[1024];
        int count = 0;
        try {
            fileInputStream = new FileInputStream(path);
            fileOutputStream = new FileOutputStream("E:\\2\\1.jpg");
            while ((count = fileInputStream.read(bytes)) != -1) {
                System.out.println(new String(bytes, 0, count));
                fileOutputStream.write(bytes, 0, count);
            }
            System.out.println("拷贝完成!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

IO常用类

FileReader 和FileWriter 介绍

FileReader相关方法

(1)new FileReader(File/String)
(2)read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
(3)read(char[])批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾则返回-1
(4)相关的API
new String(char[]):将char[]转换成String
new String(char[],off,len):将char[]的指定部分转换成String
FileReader 和 FileWriter类图

package com.FileReader;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/9/30 18:42
 */
public class FileReaderExercise {
    @Test
    public void showDoc() {
        String path = "E:\\a.txt";
        FileReader fileReader = null;

        try {
            // 1.创建一个FileReader 对象
            fileReader = new FileReader(path);
            int count = 0;
            // 字符数组读取
            char[] chars = new char[8];
            while ((count = fileReader.read(chars)) != -1) {
                System.out.print(new String(chars, 0, count));
            }
            System.out.println();
            System.out.println("文件读取完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void showDoc2() {
        String path = "E:\\a.txt";
        FileReader fileReader = null;

        try {
            // 1.创建一个FileReader 对象
            fileReader = new FileReader(path);
            int count = 0;
            // 单个字符读取
            while ((count = fileReader.read()) != -1) {
                System.out.print((char) count);
            }
            System.out.println();
            System.out.println("文件读取完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

FileWriter常用方法

(1)new FileWriter(File/String):覆盖模式,相当于流的指针在首端
(2)new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
(3)write(int):写入单个字符
(4)write(char[]):写入指定数组
(5)write(char[],off,len):写入指定数组的指定部分
(6)write(String):写入整个字符串
(7)write(string,off,len):写入字符串的指定部分
相关的API:
String类:toCharArray:将String转换成char[]
注意:
FileWriter使用后,必须要关闭(close)或者刷新(flush),否则写入不到指定的文件!

package com.FileWriter;

import org.junit.Test;

import java.io.FileWriter;
import java.io.IOException;

/**
 * @author wty
 * @date 2022/9/30 18:57
 */
public class FileWriterExercise {
    @Test
    public void writeDoc() {
        String path = "E:\\1.txt";
        String str = " 风雨之后定见彩虹";
        char[] chars = {'a', 'b', 'c'};
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(path, true);
            //fileWriter.write(str);
            //fileWriter.write('H');
            //fileWriter.write(chars);
            //fileWriter.write(str.toCharArray(),0,2);
            fileWriter.write(str, 0, 3);

            /**
             * (3)write(int):写入单个字符
             *  fileWriter.write('H');
             * (4)write(char[]):写入指定数组
             * fileWriter.write(chars);
             * (5)write(char[],off,len):写入指定数组的指定部分
             * (6)write(String):写入整个字符串
             * (7)write(string,off,len):写入字符串的指定部分
             */
            System.out.println("写入完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close(); // 一定要关闭
                //fileWriter.flush(); // flush也可以使用

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

节点流 处理流

基本介绍

  1. 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter(源码)
  2. 处理流(也叫包装流)是"连接"在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter

节点流和处理流

节点流和处理流的区别和练习

  1. 节点流是底层流/低级流,直接跟数据源相接。
  2. 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入和输出。
  3. 处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连

处理流的功能主要体现在以下两个方面

  1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
  2. 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。

处理流 BufferReader 和 BufferedWriter

BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的,关闭处理流时,只需要关闭外层流即可

BufferReader示例:

package com.BufferReader;

import org.junit.Test;

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

/**
 * @author wty
 * @date 2022/10/1 9:57
 */
public class BufferReader_ {
    @Test
    public void readText() {
        String path = "E:\\2.txt";
        BufferedReader bufferedReader = null;
        char[] chars = new char[8];
        int count = 0;
        try {
            bufferedReader = new BufferedReader(new FileReader(path));
            while ((count = bufferedReader.read(chars)) != -1) {
                System.out.println(new String(chars, 0, count));
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    /**
     * BufferReader的使用
     */
    public void readText2() {
        String path = "E:\\2.txt";
        // 创建BufferedReader 对象
        BufferedReader bufferedReader = null;
        String str = "";
        try {
            bufferedReader = new BufferedReader(new FileReader(path));
            while ((str = bufferedReader.readLine()) != null) {// 按行读取效率高
                System.out.println(str);
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedWriter示例:

package com.BufferWriter;

import org.junit.Test;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author wty
 * @date 2022/10/1 10:28
 */
public class BufferWriter_ {
    @Test
    public  void writeDoc(){
        String path = "E:\\3.txt";
        BufferedWriter bufferedWriter = null;
        char[] chars = {'1','2','3'};

        try {
            bufferedWriter = new BufferedWriter(new FileWriter(path));
            bufferedWriter.write(chars);
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Test
    public  void writeDoc2(){
        String path = "E:\\3.txt";
        BufferedWriter bufferedWriter = null;
        char[] chars = {'1','2','3'};

        try {
            bufferedWriter = new BufferedWriter(new FileWriter(path,true)); // 追加方式
            bufferedWriter.write(chars);
            bufferedWriter.newLine(); // 插入一个换行符
            bufferedWriter.write("今天天气不错");
            System.out.println("写入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

拷贝文件(字符txt文件)

package com.BufferCopy;
	
	import org.junit.Test;
	
	import java.io.*;
	
	/**
	 * @author wty
	 * @date 2022/10/1 10:41
	 */
	public class BufferCopy {
	    @Test
	    /**
	     * BufferedReader和bufferedWriter是按照字符操作的,不要操作二进制文件(声音、视频、word、文档),会造成文件损坏
	     */
	    public void bufferCopy() {
	        String path = "E:\\1\\1.txt";
	        BufferedReader bufferedReader = null;
	        String targetPath = "E:\\1\\2.txt";
	        BufferedWriter bufferedWriter = null;
	        String str = "";
	        try {
	            bufferedReader = new BufferedReader(new FileReader(path));
	            bufferedWriter = new BufferedWriter(new FileWriter(targetPath));
	
	            while ((str = bufferedReader.readLine()) != null) {
	                // 每读一行写一行
	                bufferedWriter.write(str);
	                // 插入换行符
	                bufferedWriter.newLine();
	            }
	            System.out.println("拷贝完毕!");
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                bufferedReader.close();
	                bufferedWriter.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	}

二进制文件的拷贝(声音、视频、word文档)

package com.BufferedInputCopy;

import org.junit.Test;

import java.io.*;

/**
 * @author wty
 * @date 2022/10/1 18:07
 */
public class copyExercise {
    @Test
    /**
     * 完成二进制文件的拷贝
     * BufferedInputStream 和 BufferedOutputStream的使用
     * 字节流可以操作二进制文件,也可以操作文本文件
     */
    public void copyDoc() {
        String path = "E:\\1\\1.mp4";
        String target = "E:\\1\\2.mp4";
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        byte[] bytes = new byte[1024];
        int count = 0;
        try {
            // FileInputStream 继承了 InputStream
            bufferedInputStream = new BufferedInputStream(new FileInputStream(path));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(target));
            while ((count = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, count);
            }
            System.out.println("拷贝完毕");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedInputStream.close();
                bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

对象流

ObjectInputStream和ObjectOutputStream

看一下需求:

  1. 将int num = 100这个int数据保存到文件中,注意不是100数字,而是int 100,并且,能够从文件中直接恢复int 100
  2. 将Dog dog = new Dog(“小黄”, 3); 这个dog对象保存到文件中,并且能够从文件恢复
  3. 上面的要求,就是能够将基本数据类型或者对象进行序列化和反序列化

序列化和反序列化

  1. 序列化时在保存数据时,保存数据的值数据类型
  2. 反序列化就是在恢复数据时,恢复数据的值数据类型
  3. 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一
    Serializable(可序列化的,可串行的) // 这是一个标记接口,没有方法
    Externalizable// 该接口由方法需要实现,因此我们一般实现上面的Serializable接口

基本介绍

  1. 功能:提供了对基本数据类型或者对象类型的序列化和反序列化的方法
  2. ObjectOutputStream提供 序列化功能
  3. ObjectInputStream提供 反序列化功能

序列化代码示例:

package com.ObjectStream;

import org.junit.Test;

import java.io.*;

/**
 * @author wty
 * @date 2022/10/1 19:17
 */
public class ObjectOutput {
    @Test
    public void outputStreamExercise() {
        Dog dog = new Dog("小黄", 3, "中国", "黄色");
        // 序列化后保存的文件格式不是存文本,而是按照它的格式
        String path = "E:\\1\\data.dat";

        ObjectOutputStream objectOutputStream = null;

        try {
            objectOutputStream = new ObjectOutputStream(new FileOutputStream(path));
            objectOutputStream.writeInt(100); // int 底层装箱Integer(父类是Serializable)
            System.out.println("写入int数据类型完毕");

            objectOutputStream.writeBoolean(true);
            System.out.println("写入Boolean数据类型完毕");

            objectOutputStream.writeChar('a');
            System.out.println("写入char数据类型完毕");

            objectOutputStream.writeDouble(79.99);
            System.out.println("写入Double数据类型完毕");

            objectOutputStream.writeUTF("字符串"); // 放字符串的方法
            System.out.println("写入字符串完毕");

            objectOutputStream.writeObject(dog);
            System.out.println("写入对象完毕");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                objectOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

// 如果需要序列化某个类的对象,必须要实现Serializable接口
class Dog implements Serializable {
    String name;
    int age;
    // 序列化版本号。可以提高序列化的兼容性
    private static final long serialVersionUID = 1L;

    // 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
    private static String nation;
    private transient String color; // transient:瞬间的短暂的,不会被序列化

    // 序列化对象时,要求里面属性的类型也需要实现序列化接口(每个对象)
    private Master master = new Master();

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                ", nation=" + nation +
                ", Master=" + master +
                '}';
    }

    public Dog(String name, int age, String nation, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
        this.nation = nation;
    }

    public void say() {
        System.out.println("汪汪");
    }

    public void eat() {
        System.out.println("喂食");
    }
}

反序列化示例;

package com.ObjectStream;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * @author wty
 * @date 2022/10/1 19:45
 */
public class ObjectInputStreamExercise {
    @Test
    public void objectInputSteamExercise() {
        String path = "E:\\1\\data.dat";
        ObjectInputStream objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(new FileInputStream(path));
            // 1.反序列化的顺序要和保存顺序一致,否则会出现异常
            System.out.println(objectInputStream.readInt());
            System.out.println(objectInputStream.readBoolean());
            System.out.println(objectInputStream.readChar());
            System.out.println(objectInputStream.readDouble());
            System.out.println(objectInputStream.readUTF());
            Object object = objectInputStream.readObject();
            System.out.println(object);
            System.out.println("类是:" + object.getClass());

            System.out.println("读取完毕");

            // 如果我们需要调用Dog类的方法,那么需要向下转型
            //object.say(); // 这样是不行的,需要向下转型

            Dog dog = (Dog) object;
            dog.say();
            dog.eat();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                objectInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Master类

package com.ObjectStream;

import java.io.Serializable;

/**
 * @author wty
 * @date 2022/10/1 20:37
 */
public class Master implements Serializable {
}

注意事项

(1)读写顺序要一致
(2)要求序列化或者反序列化对象,需要实现Serializable
(3)序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
(4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
(5)序列化对象时,要求里面属性的类型也需要实现序列化接口(每个对象)
(6)序列化具备可继承性,也就是如果某类已经实现了序列化,那么它的所有子类也默认实现了序列化

标准输入输出流

介绍类型默认设备
System.inInputStream键盘
System.outPrintStream显示器

传统方法System.out.println(“”);是使用out对象将数据输出到显示器。
传统方法Scanner是从标准输入键盘接收数据

package com.standard;

import java.util.Scanner;

/**
 * @author wty
 * @date 2022/10/1 23:53
 */
public class InputAndOutput {
    public static void main(String[] args) {
        //     public static final InputStream in;
        // 编译类型:InputStream
        // 运行类型:BufferedInputStream
        // 表示的是标准输入(键盘)
        System.out.println(System.in.getClass());
        // public static final PrintStream out;
        // 编译类型:PrintStream
        // 运行时类型:PrintStream
        // 标准输出(显示器)
        System.out.println(System.out.getClass());

        System.out.println("请输入字符:");
        Scanner scanner = new Scanner(System.in);
        String hi = scanner.nextLine();
        System.out.println("您输入的是:"+hi);
    }
}

转换流

InputStreamReader 和 OutputStreamWriter

字节流和字符流的相互转换

字节流:可以转换编码形式
字符流:不能转换

介绍

  1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
  2. OutpurStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
  3. 当处理纯文本数据时,如果使用字符效率高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
  4. 可以在使用时指定编码的格式比如(UTF-8,GBK,GB2312,ISO8859-1)等

InputStreamReader 示例

package com.Transfomation;

import org.junit.Test;

import java.io.*;

/**
 * @author wty
 * @date 2022/10/2 0:08
 */
public class CodeQuestion {
    public static void main(String[] args) {
        // 读取E盘下的a.txt文件
        // 创建一个字符输入流 BufferedReader [包装流]
        // 使用 BufferedReader(FileReader) 对象读取a.txt
        // 默认情况下读取文件是按照UTF-8编码来读取的
        String path = "E:\\a.txt";
        BufferedReader bufferedReader = null;
        String str = "";

        try {
            bufferedReader = new BufferedReader(new FileReader(path));
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
            }
            System.out.println("读取成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    /**
     * 转换流解决中文乱码问题
     * 字节流转换成字符流
     */
    public void TransformationExerCise() {
        String path = "E:\\a.txt";
        FileInputStream fileInputStream = null;
        InputStreamReader InputStreamReader = null;
        BufferedReader bufferedReader = null;
        String str = "";

        try {
            // 把FileInputStream 转换成了 InputStreamReader,同时指定了编码UTF-8
            fileInputStream = new FileInputStream(path);
            InputStreamReader = new InputStreamReader(fileInputStream, "GBK");
            // 把InputStreamReader 转换成 BufferedReader
            bufferedReader = new BufferedReader(InputStreamReader);
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
            }
            System.out.println("读取成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

OutpurStreamWriter 示例

package com.Transfomation;

import org.junit.Test;

import java.io.*;

/**
 * @author wty
 * @date 2022/10/2 8:38
 * 把FileOutPutStream转换成字符流OutPutStreamWriter
 * 指定的编码 GBK/UTF-8/UTF8
 */
public class OutPutStreamWriterExercise {
    @Test
    public void transporteout() {
        String path = "E:\\a.txt";
        BufferedWriter bufferedWriter = null;
        String charSet = "GBK";
        try {
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path, true), charSet));
            bufferedWriter.write("今天天气不错!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

打印流

PrintStream 和 PrintWriter

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

PrintStream示例

package com.PrintStream;

import org.junit.Test;

import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

/**
 * @author wty
 * @date 2022/10/2 8:55
 */
public class PrintStreamExercise {
    @Test
    public void PrintStream_() {
        PrintStream out = System.out;
        // 在默认情况下,PrintStream输出数据的位置是标准输出,即:显示器
        String str = "你好,小王";
        out.println(str);
        /**
         * print 的源码
         *     public void print(String var1) {
         *         if (var1 == null) {
         *             var1 = "null";
         *         }
         *
         *         this.write(var1);
         *     }
         */
        // 因为print的底层是write,所以可以用write打印
        try {
            //out.write(str.getBytes());
            // 可以更改打印流的输出设备
            System.setOut(new PrintStream("E:\\5.txt"));
            // 可以输出到E:\a.txt
            System.out.println("今天天气很好");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }
}

PrintWriter示例

package com.PrintStream;

import org.junit.Test;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author wty
 * @date 2022/10/2 9:27
 */
public class PrintWriterExercise {
    @Test
    public void PrintWriter_() {
        PrintWriter printWriter = new PrintWriter(System.out);
        printWriter.println("今天天气很好呦!");
        printWriter.close();
    }

    @Test
    public void PrintWriter_Doc() {
        // 写在文件里
        PrintWriter printWriter = null;
        try {
            printWriter = new PrintWriter(new FileWriter("E:\\2.txt"));
            printWriter.println("今天天气很好呦!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            printWriter.close();
        }
    }
}

Properties类

获取配置文件(传统方法)

示例:

  @Test
    public  void useFileClass(){
        //Properties properties = new Properties();
        String path = "src/com/PropertiesExercise/mysql.properties";
        BufferedReader bufferedReader = null;
        String str = "";

        try {
            bufferedReader = new BufferedReader(new FileReader(path));
            while ((str = bufferedReader.readLine()) != null){ // 循环读取
                System.out.println(str);
            }
        } catch (IOException e) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }
    @Test
    /**
     * 传统方法
     */
    public  void useFileClass2(){
        //Properties properties = new Properties();
        String path = "src/com/PropertiesExercise/mysql.properties";
        BufferedReader bufferedReader = null;
        String str = "";

        try {
            bufferedReader = new BufferedReader(new FileReader(path));
            while ((str = bufferedReader.readLine()) != null){ // 循环读取
                String []array = str.split("=");
                System.out.println(array[0]+ "的值是:" + array[1]);
            }
        } catch (IOException e) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

基本介绍

Properties

  1. 专门用于读写配置文件的集合类
    配置文件格式:
    健 = 值
  2. 注意:键值对不需要有空格,值不需要用引号括起来
  3. Properties常用方法
    load:加载配置文件的键值对到Properties对象
    list:将数据显示到指定设备
    getProperty(key):根据健获取值
    setProperty(ket,value):设置键值对到Properties对象
    store:将Properties中的键值对存储到配置文件,在IDEA中,保存信息到配置文件,如果有中文,将会存储为Unicode码

Properties常用方法代码示例:

/**
 * 使用类Properties
 */
@Test
public  void useFile(){
    Properties properties = new Properties();
    try {
        properties.load(new FileInputStream("src/com/PropertiesExercise/mysql.properties"));
        String ip = properties.getProperty("ip");
        System.out.println("ip:" + ip);
        String pwd = properties.getProperty("pwd");
        System.out.println("pwd:" + pwd);
        String user = properties.getProperty("user");
        System.out.println("user:" + user);
        String id = properties.getProperty("id");
        System.out.println("id:" + id);
    } catch (IOException e) {
        e.printStackTrace();
    }

}
/**
 * 使用类Properties
 */
@Test
public  void useFileReader(){
    Properties properties = new Properties();
    String path = "src/com/PropertiesExercise/mysql.properties";
    try {
        properties.load(new FileReader(path));
        String ip = properties.getProperty("ip");
        System.out.println("ip:" + ip);
        String pwd = properties.getProperty("pwd");
        System.out.println("pwd:" + pwd);
        String user = properties.getProperty("user");
        System.out.println("user:" + user);
        String id = properties.getProperty("id");
        System.out.println("id:" + id);
        System.out.println("------------------ss");
        properties.list(System.out);
    } catch (IOException e) {
        e.printStackTrace();
    }

}  

配置文件的创建和修改示例:

/**
     * 使用类Properties进行创建、修改 配置文件
     */
    @Test
    public  void modifyProperties(){
        Properties properties = new Properties();
        String path = "src/com/PropertiesExercise/create.properties";
        FileWriter fileWriter = null;
        FileReader fileReader = null;
        FileWriter fileWriter1 = null;
        try {
            // 创建
            properties.setProperty("id","吴亦凡");
            properties.setProperty("age","18");
            fileWriter = new FileWriter(path);
            properties.store(fileWriter, "id"); // 这里的String是备注

            // 修改 setProperty没有ket就是创建,有key就是修改
            fileReader = new FileReader(path);
            properties.load(fileReader);
            properties.setProperty("id","王思琪");
            fileWriter1 = new FileWriter(path);
            properties.store(fileWriter1,"id更改为王思琪");
        } catch (IOException e) {
            try {
                fileReader.close();
                fileWriter.close();
                fileWriter1.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心向阳光的天域

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值