Java学习总结------IO流

JavaIO流概述

Java中对文件内容的操作需要使用IO流,I : Input 输入,O Output 输出 流: 数据的传输。

IO流的分类

按照数据流的传输方向:分为 输入流,和输出流
Tips:此处的输入输出都是以程序作为参照物的,文件数据读入程序即为输入,程序数据写入内存即为输出。
按照数据流的传输单位: 分为 字节流,字符流

字节流:按照单个字节进行读写,即8个bit。
字符流:按照Unicode字符进行读写该字符集可以描述任意字符,每个字符占2个字节即16个bit位。
不论任何文件,在磁盘中都是将字符转换称为字节,然后将该字节文件存放在磁盘中。虽然单位不同,但传输原理是相同的,而且这两种流可以相互转换。对于纯文本文件,优先使用字符流。其它文件如视频,图片等使用字节流。
在这里插入图片描述

与IO流有关的主要有四个类:

  1. public abstract class OutputStream implements Closeable, Flushable
  2. public abstract class InputStream implements Closeable, Flushable
  3. public abstract class Writer implements Appendable, Closeable, Flushable
  4. public abstract class Reader implements Appendable, Closeable, Flushable

可以看出这四个类都是抽象类,不能直接实例化对象,因此我们操作的是它们的实现类。

Closeable接口中的close方法用于关闭流,和释放资源(IO操作属于资源处理,资源处理完毕都需要关闭),其中Closeable接口继承了AutoCloseable(自动关闭接口),因此可以借助try--catch实现自动关闭。 Flushable接口中的flush方法用于刷新缓冲区,将缓冲区的内容读入或者写出。
与文件读写有关的Filexxx系列类
FileOutputStream(数据按字节写入文件)
public static void main(String[] args) {
    String path = "test.txt";  // 相对路径
    File file = new File(path);
    try(OutputStream out = new FileOutputStream(file)){ // JDK1.7提供的自动关闭
        out.write("Hello world".getBytes());
    }catch(IOException e){
        e.printStackTrace();
    }
}

运行结果:
在这里插入图片描述

其中该构造方法有一个重载方法,即每次在文件内容后进行追加。只需在后面加一个true即可,不加默认是false。
public static void main(String[] args) {
    String path = "test.txt";  // 相对路径
    File file = new File(path);
    try(OutputStream out = new FileOutputStream(file,true)){ // JDK1.7提供的自动关闭
        out.write("Hello world".getBytes());
    }catch(IOException e){
        e.printStackTrace();
    }
}

运行结果:两个helloworld
在这里插入图片描述

FileInputStream(文件数据按字节读入程序中)
public static void main(String[] args) {
    String path = "test.txt";  // 相对路径
    File file = new File(path);
    try(InputStream in = new FileInputStream(file)){ // JDK1.7提供的自动关闭
        byte[] buff = new byte[3];
        int len = -1;
        while((len = in.read(buff)) != -1){
            System.out.println(new String(buff,0,len));
        }
    }catch(IOException e){
        e.printStackTrace();
    }
}

运行结果:(每三个一组)
在这里插入图片描述

其中在对文件进行写入的时候,文件可以不存在,会自动创建,但不会创建目录(文件路径是绝对路径),但对文件进行读入的时候需要确保文件存在。
FileWriter(数据按字符写入文件)
public static void main(String[] args) {
    String path = "hehe.txt";
    try(Writer out = new FileWriter(path)){
        out.write("天天学习,好好向上!!!");
    }catch (IOException e){
        e.printStackTrace();
    }
}

运行结果:
在这里插入图片描述

FileReader(文件数据按字符读入程序中)
public static void main(String[] args) {
    String path = "hehe.txt";
    try(Reader in = new FileReader(path)){
        char[] buff = new char[3];
        int len = -1;
        while((len = in.read(buff)) != -1){
            System.out.print(new String (buff));
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

运行结果:
在这里插入图片描述

转换流

OutputStreamWriter(字节输出流----> 字符输出流)

该类定义:public class OutputStreamWriter extends Writer
该类继承了Writer,在构造方法中,传一个OutputStream类型的对象,底层会调用Writer类的构造方法,生成一个Writer类对象,因此会实现转换。

public class TestConvertStream {
    public static void main(String[] args) {
        File file = new File("hello.txt");
        try(OutputStream output = new FileOutputStream(file);
            Writer out = new OutputStreamWriter(output)){  // 字节流转换为字符流
            out.write("你好啊,今天!");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

运行结果:
在这里插入图片描述

InputStreamReader(字节输入流----> 字符输入流)

类定义:

public static void main(String[] args) {
    File file = new File("hello.txt");
    try(InputStream input = new FileInputStream(file);
        Reader in = new InputStreamReader(input)){  // 字节流转换为字符流
        int len = -1;
        char[] buff1 = new char[3];
        System.out.print("字符流读入:");
        while((len = in.read(buff1)) != -1){
            System.out.print(new String(buff1,0,len));
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

在这里插入图片描述
用字节流读入则会出现乱码:

public static void main(String[] args) {
    File file = new File("hello.txt");
    try(InputStream input = new FileInputStream(file);
        Reader in = new InputStreamReader(input)){  // 字节流转换为字符流
        int len = -1;
        byte[] buff2 = new byte[3];
        System.out.print("字节流读入:");
        while((len = input.read(buff2))!= -1){
            System.out.print( new String(buff2,0,len));
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

运行结果:
在这里插入图片描述

内存流

内存流的操作发生在内存中,将文件的数据读入内存中,处理完毕写回源文件。

字节内存流ByteArrayOutputStream / ByteArrayInputStream
字符内存流CharArrayWriter / CharArrayReader

通过内存流实现文件的合并:

public class TestMemoryStream {
    public static void main(String[] args) throws IOException {
         File file1 = new File("hell.txt");
         File file2 = new File("hello.txt");
         String str1 = read(file1);
         String str2 = read(file2);
        System.out.println(str1 + str2);
    }
    public static String read(File file){
        try(InputStream in = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();){
            byte[] buff = new byte[3];
            int len = -1;
            while((len = in.read(buff)) != -1){
                // 将文件内容读进来,存入内存中。
                bos.write(buff,0,len);
            }
            return new String(bos.toByteArray());
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }
}

打印流

因为OutputStream只能输出字节类型,如果要输出,基本类型如int,double等就很不方便。

自定义一个打印流
import java.io.OutputStream;

/**
 * @auther plg
 * @date 2019/4/20 10:26
 */
public class TestPrintStream {
    private OutputStream out;
    public TestPrintStream(OutputStream out){
        this.out = out;
    }
    // 核心方法,任何类型都可以转换为String类型,都可以借助该方法输出
    public void print(String str){
        try {
            this.out.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void printInt(int data){
        this.print(String.valueOf(data));
    }
    public void printInt(double data){
        this.print(String.valueOf(data));
    }
    // .......
}
打印流属于装饰设计模式,核心依然是某个功能,但针对此功能进行了很多扩展。
字节打印流 public class PrintStream extends FilterOutputStream

使用练习:

public static void main(String[] args) throws FileNotFoundException {
    PrintStream out = new PrintStream(new File("hell.txt"));
    out.println(10);
    out.println("hello");
    out.println("10.1");
}

运行结果:
在这里插入图片描述

字符打印流 public class PrintWriter extends Writer
public static void main(String[] args) throws FileNotFoundException {
    PrintWriter out = new PrintWriter(new File("hell.txt"));
    out.print("Java");
    out.print("C++");
    out.print("编程语言");
    out.flush();  // 需要刷新缓冲区,负责出不来
}

运行结果:
在这里插入图片描述

缓冲流

缓冲流和其它的输入输出流本质没有什么不同,只是该流在读取数据的时候提供一个缓冲区,减少与外部设备之间的IO次数,提高效率。

猜你喜欢

转载自blog.csdn.net/weixin_43213517/article/details/89409740