Java——I/O流总结

在Java中File类对象,可以用来操作文件,但是不能处理文件内容

为了处理文件内容,进行 I/O 操作,必须使用流的操作模式来完成


I/O流体系结构图:

I/0流分类:

1)根据处理的数据类型分为:字节流和字符流

2)根据处理的数据流向分为:输入流和输出流

字节流与字符流的区别:

字节流和字符流操作的本质区别只有一个:字节流是原生的操作,而字符流是经过处理后的操作。

在进行网络数据传输、磁盘数据保存所保存所支持的数据类型只有:字节

而所有磁盘中的数据必须先读取到内存后才能进行操作,而内存中会帮助我们把字节变为字符。

字节流和字符流的具体区别总结如下:

  1. 字节流处理二进制数据,适合处理一切数据类型(对中文支持不好);字符流处理字符数据,适合处理中文。
  2. 字节流在操作时不会用到缓冲区,是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区来操作文件。

那么根据上面的分类,就可以得到以下四种基本I/O流

  • 字节输入流   OutputStream
  • 字节输出流   InputStream
  • 字符输入流   Reader
  • 字符输出流   Writer

接下来,让我们来依次了解这四种基本I/O流的使用方法

一、字节输入流  OutputStream

如果想通过程序输出内容到文件,则可以使用java.io.OutputStream

OutputStream类主要方法:

1. 将给定的字节数组内容全部输出:public void write(byte b[]) throws IOException
2. 将部分字节数组内容输出:public void write(byte b[], int off, int len) throws IOException
3. 输出单个字节:public abstract void write(int b) throws IOException

范例:实现文件的内容输出

import java.io.*;
public class Test1 {
    public static void main(String[] args) {
        File file =new File("C:"+File.separator+"Users"+File.separator+"10320"+
                File.separator+"ideaProjects"+File.separator+"file.txt");
       if(!file.getParentFile().exists()){//判断父目录存在
           file.getParentFile().mkdirs();//创建多级父目录
       }
        // OutputStream是一个抽象类,所以需要通过子类进行实例化,此时只能操作File类
        try {
            OutputStream output=new FileOutputStream(file);
            //此构造方法会不断覆盖内容
            //如果变为以下构造方法,即可实现追加内容
            // OutputStream output=new FileOutputStream(file,true);
            String message="hello word";
            output.write(message.getBytes());//将内容变为字节数组
            output.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意:由于OutputStream是一个抽象类,不能实例化对象,所以要想为父类实例化,就必须要使用子类(子类实现抽象父类的方法,但是自身并不是抽象类,所以可以实例化对象)。由于方法名称都由父类声明好了,所以我们在此处只需要关系子类的构造方法。如果要进行文件的操作,可以使用FileOutputStream类来处理。

FileOutputStream类的构造方法如下:

1. 接收File类(覆盖):public FileOutputStream(File file) throws FileNotFoundException
2. 接收File类(追加):public FileOutputStream(File file, boolean append)

二、字节输出流  InputStream

使用InputStream类,可以在程序中读取文件内容

InputStream类主要方法:

1. public int read(byte b[]) throws IOException

读取数据到字节数组中,返回数据的读取个数。如果此时开辟的字节数组大小大于读取的数据大小,则返
回的就是读取个数;如果要读取的数据大于数组的内容,那么这个时候返回的就是数组长度;如果没有
数据了还在读,则返回-1

2. public int read(byte b[], int off,int len) throws IOException

读取部分数据到字节数组中,每次只读取传递数组的部分内容,如果读取满了则返回长度(len),如果没有
读取满则返回读取的数据个数,如果读取到最后没有数据了返回-1

3. public abstract int read() throwsIOException

读取单个字节,每次读取一个字节的内容,直到没有数据了返回-1

范例:实现文件信息的读取

public class Test1 {
    public static void main(String[] args) {
        //定义文件路径
        File file = new File("C:" + File.separator + "Users" + File.separator + "10320" +  File.separator + "ideaProjects" + File.separator + "file.txt");
        if(file.exists()){
            try {
       // InputStream类是抽象类,必须利用其子类FileInputStream实例化对象,此时只能处理File类
                InputStream input=new FileInputStream(file);//构造方法
                byte[] data =new byte[1024];//每次可以读取的最大数量
                int len=input.read(data);//此时的数据读取到了数组当中
                String result = new String(data,0,len) ; // 将字节数组转为String
                System.out.println("读取内容【"+result+"】") ;
                input.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

三、字符输入流  Reader

Reader是字符输入流的处理类,可以通过程序实现读取文件内容

Reader类主要方法:

  1. public abstract  int read()throws IOException   读取单个字符
  2. public int read(char[] c) throws IOException      读取数据到字符数组                                                                            
  3. public int read(char[] c,int off,int len) throws IOException       读取部分数据到字符数组                                                                                             

在Reader类中没有方法可以直接读取字符串类型,这个时候只能通过字符数组进行读取操作

范例:通过Reader类读取文件内容

public class Test1 {
    public static void main(String[] args) {
        //定义文件路径
        File file = new File("C:" + File.separator + "Users" + File.separator 
+ "10320" +  File.separator + "ideaProjects" + File.separator + "file.txt");
        if(file.exists()){
            try {
                // Reader类是抽象类,必须利用其子类FileReader实例化对象,此时只能处理File类
                    Reader in = new FileReader(file) ;
                    char[] data = new char[1024] ;
                    int len = in.read(data) ; // 将数据读取到字符数组中
                    String result = new String(data, 0, len) ;
                    System.out.println("读取内容【"+result+"】") ;
                    in.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四、字符输出流   Writer

字符流适合于处理中文数据,Writer是字符输出流的处理类,可以通过程序实现向文件写入内容

Writer类主要方法:

  1. public void write(String str) throws IOException     将str字符串直接输出到输出流中
  2. public void write(String str,int off,int len) 将str字符串里从off位置开始长度为len的字符输出到输出流中

范例:通过Writer类实现输出

public class Test1 {
    public static void main(String[] args) {
        //定义文件路径
        File file = new File("C:" + File.separator + "Users" + File.separator + "10320" + File.separator + "ideaProjects" + File.separator + "file.txt");
        if (!file.getParentFile().exists()) { // 必须保证父目录存在
            file.getParentFile().mkdirs() ; // 创建多级父目录
        }
        String message = "hello world";
        try (Writer out = new FileWriter(file)) {
            out.write(message);
            out.close();
        }catch(Exception e){
            e.printStackTrace();
    }
        }
    }

总结:

1.不管使用的是字节流还是字符流,其基本的操作流程是一样的:

  1.  根据文件路径创建File类对象 ;
  2.  根据字节流或字符流的子类实例化父类对象 ;
  3. 进行数据的读取或写入操作
  4. 关闭流(close())

2.在进行文件输出的时候,所有的文件会自动帮助用户创建,不在需要调用createFile()方法手工创建。

3.OutputStream类、InputStream类、Reader类、Writer类都是抽象类,如果要对它们实例化,必须使用它们的子类。

4.在进行IO处理的时候,如果处理的是图片、音乐、文字都可以使用字节流,而只有处理中文的时候才会使用字符流。

5.所有字符流的操作,无论是写入还是输出,数据都要先保存在缓存中,如果字符流不关闭,数据就有可能保存在缓存中并没有输出到目标源。这种情况下就必须使用flush()方法强制刷新才能够得到完整数据

6.  InputStream input=new FileInputStream(file);将file对象作为参数传入根据FileInputStream类的构造方法决定

发布了50 篇原创文章 · 获赞 39 · 访问量 8295

猜你喜欢

转载自blog.csdn.net/Racheil/article/details/89153789