I/O流(超详细)

1 - File类


1.1 - 基本概念

        java.io.File类用于描述文件和目录的路径信息,可以获取文件的大小等相关属性。

1.2 - 构造方法

方法名说明
File(String pathName)通过给定参数的路径名字符串转换成File对象
File(String parent,String child)从父类的路径名和子类的文件名来创建一个FIle对象
File(File parent,String child)从父类的File目录对象和子类的文件名来创建一个File对象
/**
 * @author Mr.乐
 * @data 2022/8/7  0:29
 */
public class Demo01 {
    public static void main(String[] args) {
        //完整的一个字符串类型路径和文件名转换成File对象
        File file = new File("./myTest.txt");//创建File对象
        System.out.println(file);
        //.\myTest.txt
        //将路径和文件名拆分成两部分组成一个完整的File对象
        File file1 = new File("./", "myTest.txt");
        System.out.println(file1);
        //.\myTest.txt
        //将路径和文件名拆分成两部分组成一个完整的File对象
        File file2 = new File("./");//创建路径的File对象,作为构造方法中的第一个参数
        File file3 = new File(file2, "myTest.txt");
        System.out.println(file3);
        //.\myTest.txt
    }
}

1.3 - File类的创建功能

方法名说明
boolean createNewFile()创建文件
boolean mkdir()创建目录(单个)
boolean mkdirs()创建目录(多级)
/**
 * @author Mr.乐
 * @Description File类的创建功能
 */
public class Demo02 {
    public static void main(String[] args) throws IOException {
        File file = new File("./myTest.txt");//创建File对象与文件相关联
        if(file.createNewFile()){
            System.out.println("文件创建成功!~");
        }else {
            System.out.println("文件创建失败!~");
        }
        //创建单个目录
        File file1 = new File("./myDir");//创建File对象与目录相关联
//        if(file1.mkdir()){
        if(file1.mkdirs()){//使用创建多级目录的方法创建单个目录,可以。
            System.out.println("目录创建成功!~");
        }else {
            System.out.println("目录创建失败!~");
        }

        //创建多级目录
        File file2 = new File("H/E/L/L/O");
//        if (file2.mkdir()){mkdir方法不能创建多级目录
        if (file2.mkdirs()){
            System.out.println("多级目录创建成功!~");
        }else {
            System.out.println("多级目录创建失败!~");
        }
    }
}

1.4 - File类的常用功能

方法名说明
boolean isDirectory()判断File对象指向的是否是一个目录
boolean isFile()判断File对象指向的是否是一个文件
boolean exists()判断File对象指向的文件或目录是否存在,存在则返回true
String getAbsolutePath()获取File对象指向文件的绝对路径
String getPath()获取File对象创建时指向文件的路径和文件名
String getName()获取创建File对象的文件名
String getParent()获取创建File对象所在的目录名称
String[] list()获取File对象中所有的文件(字符串形式)
File[] listFiles()获取File对象中所有的文件(File对象形式)
long lastModified()获取File对象指向文件的最后被修改时间
/**
 * @author Mr.乐
 * @Description
 */
public class Demo03 {
    public static void main(String[] args) {
        File file = new File("./");//指的是项目的根目录
        File file1 = new File("./a.txt");//不存在
        File file2 = new File("./myTest.txt");//存在的文件
        File file3 = new File("./myDir");//存在的目录
        //判断是否是目录
        System.out.println(file.isDirectory()); // true
        System.out.println(file1.isDirectory());//f
        System.out.println(file2.isDirectory());//f
        System.out.println(file3.isDirectory());//true
        System.out.println("---------------------------------------");
        //判断是否是文件
        System.out.println(file.isFile());  //  f
        System.out.println(file1.isFile());//   f
        System.out.println(file2.isFile());  //t
        System.out.println(file3.isFile());  //f
        System.out.println("---------------------------------------");
        //判断是否存在
        System.out.println(file.exists());
        System.out.println(file1.exists());  //false
        System.out.println(file2.exists());
        System.out.println(file3.exists());
        System.out.println("---------------------------------------");
        //获取绝对路径
        System.out.println(file.getAbsolutePath());
        System.out.println(file1.getAbsolutePath());
        System.out.println(file2.getAbsolutePath());
        System.out.println(file3.getAbsolutePath());
        System.out.println("---------------------------------------");
        //获取相对路径
        System.out.println(file.getPath());
        System.out.println(file1.getPath());
        System.out.println(file2.getPath());
        System.out.println(file3.getPath());
        System.out.println("---------------------------------------");
        //获取文件名
        System.out.println(file.getName());
        System.out.println(file1.getName());
        System.out.println(file2.getName());
        System.out.println(file3.getName());
        System.out.println("---------------------------------------");
        //获取文件所在的目录名
        System.out.println(file.getParent());
        System.out.println(file1.getParent());
        System.out.println(file2.getParent());
        System.out.println(file3.getParent());
        System.out.println("---------------------------------------");
        //获取File对象指向目录内部的所有内容以字符串形式
        String[] list = file.list();
        for (String name : list) {
            System.out.println(name);
        }
        System.out.println("---------------------------------------");
        //获取File对象指向目录内部的所有内容以File类型
        File[] files = file.listFiles();
        for (File f : files) {
            System.out.println(f);
        }
        System.out.println("---------------------------------------");
        //获取文件最后被修改的时间
        long time = file2.lastModified();
        Date date = new Date(time);//将long的毫秒数转换成Date类型引用
        //创建一个时间格式化的类
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String newTime = sdf.format(date);//将date类型进行格式化
        System.out.println(newTime);
    }
}

1.5 - File类的删除功能

方法名说明
boolean delete()删除文件或(空)目录
/**
 * @author Mr.乐
 * @Description   File的删除功能
 */
public class Demo04 {
    public static void main(String[] args) throws IOException {
//        File file = new File("./a.txt");//不存在
//        System.out.println(file.delete());//删除一个不存在的文件时,返回false
        File file = new File("./myTest.txt");//存在的
        System.out.println(file.delete());//ture
        //删除目录
        File dirs = new File("./H");//多级目录
        File dir = new File("./myDir");//单个目录
        //删除多级目录
        if(dirs.exists()){//存在则返回真
            if(dirs.delete()){//删除目录,如果目录中有内容,就不能被删除
                System.out.println("目录删除成功!~");
            }else{
                System.out.println("目录删除失败!~");
            }
            //删除单个目录
            if(dir.exists()){//判断目录是否存在
                if(dir.delete()){//存在,则直接删除
                    System.out.println("目录删除成功!~");
                }else{
                    System.out.println("目录删除失败!~");
                }
            }
        }
    }
}

1.5.1 - 递归删除多级目录

思路:

        先删除掉目录内部的内容后,才能删除本身目录。

/**
 * @author Mr.乐
 * @Description  递归实现多级目录的删除
 */
public class Demo05 {
    public static void main(String[] args) {
        File file = new File("./H");//创建目录的File对象
//        System.out.println(file.delete());//false,因为目录内有数据,所以不能直接删除
        delDir(file);
    }

    /**
     * 递归删除多级目录
     *
     * @param file 指向目录的File对象的引用
     */
    private static void delDir(File file) {
        File[] files = file.listFiles();//相当于打开目录,查看内部的内容
        if (files.length > 0) {//如果数组长度大于0,说明目录内部有数据
            for (File f : files) {
                if (f.isDirectory()) {//判断是否是一个目录
                    delDir(f);
                } else {
                    f.delete();//如果是文件,则直接删除
                }
            }
        }
        file.delete();
    }
}

1.6 - 修改文件后缀名

        将指定目录下的所有文件后缀名为txt统一修改成md。

/**
 * @author Mr.乐
 * @Description 修改文件后缀名
 */
public class Demo06 {
    public static void main(String[] args) {

    }
    /**
     * 修改file引用执行的目录下的以txt为结尾的文件改成md
     * @param file
     */
    private static void renameFile(File file) {
        if(file.exists()){//判断目录是否存在
            File[] files = file.listFiles();//存在,则打开目录,查看内容
            for (File f :  files) {//依次取出目录中的每个文件
                if(f.isFile()){//判断是否是文件
                    if(f.getName().endsWith("txt")){//再次判断文件名是否以txt为结尾
                        String parent = f.getParent();//文件所在目录的路径
                        System.out.println(parent);
                        String name = f.getName();//获取文件名  a.txt
                        System.out.println(name);
                        //lastIndexOf方法找到最后出现的.的位置
                        String newName = name.substring(0, name.lastIndexOf(".")) + ".md";
                        File file1 = new File(parent, newName);//创建一个新的文件的File对象
                        f.renameTo(file1);//实现文件名的重写
                    }
                }else{
                    renameFile(f);//如果不是文件,就是目录,就需要使用递归重复打开的操作
                }
            }
        }
    }
}

2 - I/O字节流

2.1 - I/O分类

I/O : Input(输入) / Output(输出)

流:是一种抽象的概念,数据传输的总称,就是说数据在设备之间传输称之为流,流的本质就是传输。

常见的数据传输的形式:文件的复制、上传、下载。

  • 根据数据的流向

    • 输入流:读数据

    • 输出流:写数据

一定要站在内存的角度去考虑,以内存为基准去理解

  • 根据数据的类型

    • 字节流(万能流):所有通过编译器打开之后看不懂的都是字节流

      • 字节输入流

      • 字节输出流

    • 字符流 : 通过文本编译器打开能看懂的

      • 字符输入流

      • 字符输出流

2.2 - 字节流写数据

  • OutputStream - 字节输出流

方法名说明
FileOutputStream(String name)根据参数指定的路径名来构造对象并与文件关联。
FileOutputStream(String name, boolean append)以追加写的方式构造对象
void write(int b)用于将参数指定的单个字节写入输出流中
void write(byte[] b)用于将参数指定的字节数组全部写入到输出流中
void write(byte[] b , int off, int len)用于将数组中一部分内容写入输出流。
void close()关闭输出流并释放资源
/**
 * @author Mr.乐
 * @Description  将数据通过字节输出流写入到文件中
 */
public class FileOutputStream01 {
    public static void main(String[] args) throws IOException {
       //创建字节输出流对象,与文件相关联
        FileOutputStream fos = new FileOutputStream("./myTest.txt");  //覆盖写
        //单个字节写入,通过字符编码
//        fos.write(65);
//        fos.write(66);
        //输入26个英文字母写入到文件中
//        for (int i = 0; i < 26; i++) {
//            fos.write(65 + i);
//        }
        //写一整个 byte数组内容
//        byte[] bytes = {97,98,99,101,101,102};
//        fos.write(bytes);
        //写byte数组中的一部分内容
        byte[] bytes = "1234567890张三".getBytes();//getBytes方法将字符串转换成byte类型数组
//        fos.write(bytes,0,10);//从数组中第一个位置开始写,写10个长度的内容
        fos.write(bytes,0,16);//utf-8的编码格式下,一个中文占三个字节长度
        //关闭流并释放资源
        fos.close();
    }
}

        是否采用追加写,取决于构造方法中的第二个参数,true:则表示追加写,false或不写第二个参数,则表示覆盖写。

注意:

        utf-8的编码格式下,一个中文占三个字节长度!

2.3 - 字节流异常处理

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

/**
 * @author Mr.乐
 * @Description  字节流异常处理方式
 */
public class FileOutputStream02 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("./myTest.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {//无论异常是否出现,都会执行的语句块,一般做善后处理
            try {
                fos.close();//关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.4 - 字节流读数据

  • InputStream - 字节输入流

方法名说明
FileInputStream(File file)根据参数指定的File对象来创建字节输入流对象
FileInputStream(String name)根据参数指定的字符串路径名来构造对象并关联起来
int read()用于从输入流中读取单个字节的数据
int read(byte[] b)用于从输入流中读取数组长度个字节数据
int read(byte[] , int off,int len)用于从输入流中读取数组中一部分内容
void close()关闭输入流并释放资源
/**
 * @author Mr.乐
 * @Description  字节输入流读取数据
 */
public class FileInputStream01 {
    public static void main(String[] args) throws IOException {
        File file=new File("./myTest.txt");//创建File对象,作为输入流的参数
        FileInputStream fis = new FileInputStream("./myTest.txt");//创建字节输入流对象
        //单个字节读取
//        int by=fis.read();
//        System.out.println(by);
        //当读文件读完时,会返回-1
        //循环方式读取
        int by;
        while ((by = fis.read()) != -1){//当读取出来的字符编码不是-1时,说明文件还有内容
            System.out.println((char)by);//读取一次,输出一次
        }

        fis.close();//关闭输入流
    }
}
  • 一次读取一个数组

/**
 * @author Mr.乐
 * @Description  字节输入流读取数据
 */
public class FileInputStream02 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("./myTest.txt");//创建输入流对象
        //提供byte类型数组,用来存储读取出来的数据
        byte[] bytes = new byte[13];  //如果数组不够大,则将数据进行截取
//        int length = fis.read(bytes);
        //使用数组的方式读取时,返回的int类型的数据是数组中实际数据的长度
//        System.out.println(new String(bytes,0,length));

        //使用数组的方式循环读取数据
        int len;//存储读取数组中数据的实际长度
        while ((len = fis.read(bytes)) != -1){//当返回-1,则表示数据读完了
            System.out.println(new String(bytes,0,len));//读取一次,输出一次
        }
        fis.close();//关闭输入流
    }
}
  • 字节流读一个字节写一个字节

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

/**
 * @author Mr.乐
 * @Description
 */
public class Input_Output_01 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("./myTest.txt");//创建字节输入流对象
        FileOutputStream fos = new FileOutputStream("./newMyTest.txt");//创建字节输出流对象
        int by;//用来存字符编码
        while ((by = fis.read()) != -1){
            //从输入流中读取一个字节后,再次写入到输出流中
            fos.write(by);
        }

        //关闭流
        fis.close();
        fos.close();
    }
}
  • 字节流实现图片复制(图片可以用就行)

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

/**
 * @author Mr.乐
 * @Description  字节流实现图片复制过程
 */
public class Input_Output_02 {
    public static void main(String[] args) throws IOException {
//创建字节输入流读取图片
        FileInputStream fis = new FileInputStream("./pic.jpg");
        //字节输出流将字节写入到新的文件中
        FileOutputStream fos = new FileOutputStream("./newPic.jpg");
        //一次读写一个字节
//        int by;
//        while ((by = fis.read()) != -1){
//            fos.write(by);
//        }  效率低
        //一次读取一个数组
        byte[] bytes = new byte[1024];//创建数据缓冲区,用来存放读出来的数据
        int len;//存储数组中实际数据的长度
        while ((len = fis.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }
        //关闭流
        fis.close();
        fos.close();
    }
}

2.5 - 字节流缓冲区

  • BufferedOutputStream

  • BufferedInputStream

        将字节流进行封装,会大大的提高运行效率

import java.io.*;

/**
 * @author Mr.乐
 * @Description  各种文件复制方式效率对比
 */
public class All_01 {
    public static void main(String[] args) throws IOException {
        final String SRC = "./video.mp4";
        final String TO = "./newVideo.mp4";

//        System.currentTimeMillis()作用获取1970.1.1 0:0:0 到系统时间的毫秒数
        long startTime = System.currentTimeMillis();
//        method01(SRC,TO);//共耗时:114959ms
//        method02(SRC,TO);//共耗时:205ms
      //  method03(SRC,TO);//共耗时:912ms
      //  method04(SRC,TO);//共耗时:51ms
        long endTime = System.currentTimeMillis();
        System.out.println("共耗时:" + (endTime - startTime) + "ms");
    }
    /**
     * 基本字节流:一次读取一个字节
     * @param src
     * @param to
     */
    private static void method01(String src, String to) throws IOException {
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(to);
        int by;
        while ((by = fis.read()) != -1){
            fos.write(by);
        }
        fis.close();
        fos.close();
    }
    /**
     * 基本字节流:一次读写一个数组
     * @param src
     * @param to
     */
    private static void method02(String src, String to) throws IOException {
        //创建字节输入输入流对象
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(to);

        byte[] bytes = new byte[1024];//用来存储读出来的数据
        int len;//用来存储读出来的数组中实际数据的长度
        while ((len = fis.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }

        //关闭流
        fis.close();
        fos.close();
    }
    /**
     * 缓冲区字节流:一次读写一个字节
     * @param src
     * @param to
     */
    private static void method03(String src, String to) throws IOException {
        //创建缓冲区字节输入输出流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(to));
        int by;
        while ((by = bis.read()) != -1){
            bos.write(by);
        }
        //关闭流
        bis.close();
        bos.close();
    }
    /**
     * 缓冲区字节流 : 一次读写一个数组
     * @param src
     * @param to
     */
    private static void method04(String src, String to) throws IOException {
        //创建缓冲区字节输入输出流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(to));
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }
        //关闭流
        bis.close();
        bos.close();
    }
}

3 - I/O字符流

3.1 - 概述

一个英文、汉字以及标点符号的存储就是其对应的字符存储形式。

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * @author Mr.乐
 * @Description  不同的编码格式占中文的字节数不同
 */
public class Encoding01 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = "ZS张三";
//        byte[] bytes = str.getBytes("utf-8");//3个字节代表一个中文
        byte[] bytes = str.getBytes("GBK");//2个字节代表一个中文

        System.out.println(Arrays.toString(bytes));
        //汉字的字符编码都是负数
    }
}

 

3.2 - 编码与解码

  • 编码

    • getBytes():使用平台默认的字符集(平台指IDEA)

    • getBytes(String charSetName):使用指定的字符集

  • 解码

    • String(byte[] bytes) : 使用平台默认的字符集解码

    • String(byte[] bytes , String charSetName):使用指定字符集解码

import java.io.UnsupportedEncodingException;

/**
 * @author Mr.乐
 * @Description  编码与解码
 */
public class Encoding02 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = "ZS张三";
        //编码
//        byte[] bytes = str.getBytes();//默认使用平台字符集进行编码utf-8
        byte[] gbks = str.getBytes("GBK");

        //解码
//        String gbk = new String(bytes, "GBK");
        String s = new String(gbks);//使用平台默认的字符集进行解码
        System.out.println(s);
    }
}

3.3 - 字符流写数据

OutputStreamWriter

/**
 * @author Mr.乐
 * @Description  字符流写数据
 */
public class OutputStreamWriter01 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("./myTest.txt"));
        //        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./myTest.txt",true));
        //写一个字符
//        osw.write(65);
//        osw.write('X');
        //写一个字符串
//        osw.write("你好,JavaSE");
//        osw.write("1234567890",5,5);
        //写一个字符数组
        char[] chs = {'a','b','c','d','e','f','g'};
//        osw.write(chs);//写全部内容
        osw.write(chs,4,3);//写数组中一部分内容
        //关闭流并释放资源
        osw.close();
    }
}

3.4 - 字符流读数据

InputStreamReader

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

/**
 * @author Mr.乐
 * @Description  字符流读数据
 */
public class InputStreamReader01 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("./myTest.txt"));
        //一次读取一个字符
//        int ch;
//        while ((ch = isr.read()) != -1){//循环一次读出一个字符编码存放到ch中
//            System.out.println((char)ch);//打印ch
//        }
        //一次读取一个数组
        char[] chs = new char[1024];  //创建字符数组缓冲区,用于存储读出来的数据
        int len;//存的是数组中存储的实际数据的长度
        while((len=isr.read(chs))!=-1){
            System.out.println(new String(chs,0,len));//解码
        }
        isr.close();
    }
}

3.5 - 字符流的文本拷贝

import java.io.*;

/**
 * @author Mr.乐
 * @Description  字符流文本拷贝
 */
public class Writer_Reader_01 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流和字符输出流对象
        InputStreamReader isr = new InputStreamReader(new FileInputStream("./exception.md"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("./exc.md"));

        //单个字符的方式读写
       /* int ch;
        while ((ch = isr.read()) != -1){//读一个字符
            osw.write(ch);//写一个字符
        }*/

        //一次读取一个字符数组
        char[] chars = new char[1024];//用来存储读取出来的数据
        int len;//存储数组中实际数据的长度
        while ((len = isr.read(chars)) != -1){//读一个数组
            osw.write(chars,0,len);//写一个数组
        }

        //关闭流
        isr.close();
        osw.close();

    }
}

 

3.6 - 字符流简化写法

  • FileReader

  • FileWriter

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

/**
 * @author Mr.乐
 * @Description 字符流简化写法
 */
public class Writer_Reader_02 {
    public static void main(String[] args) throws IOException {
        //创建简化写字符输入输出流对象
        FileReader fr = new FileReader("./exception.md");
        FileWriter fw = new FileWriter("./exc.md");
        //一次读写一个字符
//        int ch;
//        while ((ch = fr.read()) != -1){
//            fw.write(ch);
//        }
        //一次读写一个字符数组
        char[] chars = new char[1024];
        int len;
        while ((len = fr.read(chars)) != -1){
            fw.write(chars,0,len);
        }
        //关闭流
        fr.close();
        fw.close();
    }
}

3.7 - 缓冲区 - 高效读写

  • BufferedReader

  • BufferedWriter

import java.io.*;

/**
 * @author Mr.乐
 * @Description 缓冲区 - 高效读写
 */
public class Writer_Reader_03 {
    public static void main(String[] args) throws IOException {
        final String SRC = "./exception.md";
        final String DEST = "./exc.md";

        //创建字符输入输出流缓冲区对象
//        BufferedReader br = new BufferedReader(new FileReader(SRC));
//        BufferedWriter bw = new BufferedWriter(new FileWriter(DEST));

        BufferedReader br = new BufferedReader(new InputStreamReader(
                new FileInputStream(SRC)));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(DEST)));

        char[] chars = new char[1024];
        int len;
        while ((len = br.read(chars)) != -1){
            bw.write(chars,0,len);
        }

        //关闭流
        br.close();
        br.close();
    }
}
  • 字符流缓冲区的特有方法

    • BufferedWriter - void newLine(); 插入新的换行符

      -void flush();刷新输出流

    • BufferedReader - String readLine();读取一行

import java.io.*;

/**
 * @author Mr.乐
 * @Description 缓冲区高效读写特有方法
 */
public class Writer_Reader_04 {
    public static void main(String[] args) throws IOException {
        //创建缓冲区字符输入输出流对象
        BufferedReader br = new BufferedReader(new FileReader("./myTest.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("./newMyTest.txt"));
        String line;//用来存储读取一行出来的字符串
        while ((line = br.readLine()) != null){
            bw.write(line);//写一行
            bw.newLine();//插入一个换行符,换行
            bw.flush();//手动刷新
        }
        //关闭流
        br.close();
//        bw.close();//在关闭流的时候,流会自动刷新一次。
    }
}

4 - 标准输入/输出/错误流

4.1 - System.in

import java.io.*;

/**
 * @author Mr.乐
 * @Description  标准输入流
 */
public class System_in {
    public static void main(String[] args) throws IOException {
        //自己封装标准输入流
        InputStream in = System.in;//获取标准输入流对象
        InputStreamReader isr = new InputStreamReader(in);//将字节流包装成普通字符流
        BufferedReader br = new BufferedReader(isr);//将普通字符流封装成缓冲区字符流
        //创建缓冲区字符输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("./myTest.txt")));

        String line;//用来存储从键盘读进来的数据
        while (true){
            if((line = br.readLine()).equals("exit")){//如果用户输入exit表示结束聊天
                System.out.println("聊天结束~");
                break;
            }
            //把用户输入的内容写入到文件中
            bw.write(line);//写一行
            bw.newLine();//换一行
            bw.flush();//手动刷新
        }
        //关闭流
        br.close();
        bw.close();
    }
}

4.2 - System.out

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author Mr.乐
 * @Description  标准输出流
 */
public class System_out {
    public static void main(String[] args) throws IOException {
        //        System.out.println("标准打印输出");
        //自己封装缓冲区标准输出流
//        PrintStream out = System.out;//标准输出流
//        OutputStreamWriter osw = new OutputStreamWriter(out);//将标准输出封装成普通字符流
//        BufferedWriter bw = new BufferedWriter(osw);//将普通的字符流封装成缓冲区字符输出流
        //同等于
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        bw.write("自己封装的缓冲区字符流");

        bw.close();//不要忘记关闭流,因为有刷新动作
    }
}

4.3 - System.err

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author Mr.乐
 * @Description  标准错误流
 */
public class System_error {
    public static void main(String[] args) throws IOException {
        System.out.println("标准输出流中的内容");
//        System.err.println("标准错误流中的内容");
        //标准错误流:打印内容颜色呈现红色,并且带有优先级高的特性,但是并不是每次都会体现出优先级的特点。
        //自己封装标准错误流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.err));
        bw.write("自己封装的标准错误流!~");
//        bw.flush();//手动刷新

        bw.close();//关闭流中有自动刷新功能,将错误流进行刷新,从而将内容输出
        //自己封装的标准错误流,有颜色呈现红色的特性,没有优先级。
    }
}

5 - 对象的持久化存储

5.1 - 对象的串行化(序列化)操作

  • ObjectOutputStream

  • ObjectInputStream

import java.io.Serializable;
import java.util.Objects;

/**
 * @author Mr.乐
 * @Description
 */
/*   将Student类使用串行化操作时,需要将该类实现Serializable接口*/
public class Student implements Serializable {
    private String name;
    private Integer age;

    public Student() {
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
-------------------------------------------------------------------------------
import java.io.*;

/**
 * @author Mr.乐
 * @Description 对象的串行化操作
 */
public class Object_01 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student stu = new Student("Andy", 18);//创建学生对象
        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("./myTest.txt"));
        oos.writeObject(stu);//将学生对象通过输出流写入到文件中
        oos.close();//关闭流


        //创建输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./myTest.txt"));

        Student newStu = (Student) ois.readObject();//从输入流中读取学生对象

        System.out.println(newStu);//打印学生对象

        ois.close();//关闭流
    }
}

出现的的问题

        1、实体类序列化后不可改变类中的方法,否则报错。

解决办法:

        找到序列化编号后在实体类中定义成常量:private static final long serialVersionUID=;

        2、屏蔽序列化transient

5.3 - 串行化存储多个学生对象

/**
 * @author Mr.乐
 * @Description
 */
public class All_02 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Student[] students = new Student[8];//创建Student类型数组,用来存储多个学生对象
        students[0] = new Student("stuOne",20);
        students[1] = new Student("stuTwo",21);
        students[2] = new Student("stuThree",22);
        students[3] = new Student("stuFour",23);
        students[4] = new Student("stuFive",24);
        students[5] = new Student("stuSix",25);
        students[6] = new Student("stuSeven",26);
        students[7] = new Student("stuEight",27);
        //        saveStu(students);//将多个学生对象存到文件中
        Student[] newStu = loadStu();//将文件中的多个学生对象加载到内存中
        for (Student stu : newStu) {
            System.out.println(stu);
        }
    }
    /**
     * 将文件中的多个学生对象加载到内存中
     *     }
     */
    private static Student[] loadStu() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./myTest.txt"));
        Student[] stuArr = (Student[]) ois.readObject();//从输入流中读取数组对象
        ois.close();//关闭流
        return stuArr;
    }
    /**
     * 将多个学生对象存到文件中
     * @param students
     */
    private static void saveStu(Student[] students) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("./myTest.txt"));
        oos.writeObject(students);//把数组引用通过串行化操作写入到文件中
        oos.close();//关闭流
    }
}

总结

        以上就是我对IO流的汇总了,IO流主要用于传输文件时将数据转化为流的形式传输。希望大家可以根据本文章更加了解IO流!

 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mr.乐.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值