美文网首页
java IO流操作

java IO流操作

作者: _Jun | 来源:发表于2020-11-26 11:07 被阅读0次

    什么是IO流?

    Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

    输入输出(IO):
    输入输出是指计算机同任何外部设备之间的数据传递。

    在IO流里,输入输出分为4步:格式化/解析,缓冲,编码转换和传递。
    格式化/解析:在内部数据表示(以字节为单位)与外部数据表示(以字符为单位)之间进行双向转换。例如一个2字节的整数10002,就需要5个字符来表示。

    缓冲:用于在格式/解析与传递之间缓存字符序列。对于输出,较短的字符序列格式化之后并不马上输出,而是保存在缓冲区里,待累积到一定规模之后再传递到外部设备。相反,从外部设备读入的大量数据也是先放在缓冲区,然后逐步取出完成输入。默认时,IO流的输入输出都是经过缓冲的,也可以让IO流工作在无缓冲模式下。

    编码转换:是将一种字符表达式转换成另一种字符表达式。如果格式化产生的字符表达式与外部字符表达式不同(输出时),或者外部表达式与IO流能解析的表达式不同(输入时),就必须进行编码转换。如多字节编码与宽字符编码之间的转换等。多数情况下并不需要进行编码转换。

    传递:主要是与外部设备进行通信。输出时,传递负责将经过格式化、缓冲即编码转换后的字符序列发送到外部设备;输入时,则负责将外部设备抽取数据,为其后进行的编码转换、缓冲及解析提供字符序列。

    IO流的分类:

    根据数据的流向分为:

    • 输入流 :把数据从其他设备上读取到内存中的流,只能进行读操作。
    • 输出流 :把数据从内存 中写出到其他设备上的流,只能进行写操作。

    根据数据的类型分为:

    • 字节流 :以字节为单位,读写数据的流。
    • 字符流 :以字符为单位,读写数据的流。

    字节流和字符流的区别:

    • 读写单位不同:字节流以字节为单位,字符流以字符为单位
    • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
    • 字节流:一次读入或读出是8位二进制。
    • 字符流:一次读入或读出是16位二进制。

    分类之后对应的超类(超类也就是父类的意思)

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

    注:
    由这四个类的子类名称基本都是以其父类名作为子类名的后缀。

    字节输入流 InputStream:

    • InputStream 是所有的字节输入流 的父类,它是一个抽象类。
    • ByteArrayInputStreamStringBufferInputStreamFileInputStream 是三种基本的介质流,它们分别从Byte 数组StringBuffer、和本地文件中读取数据。
    • PipedInputStream 是从与其它线程共用的管道中读取数据。
    • ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。
    FileInputStream fis = new FileInputStream("xxx.txt");//创建流对象    
    int b;
    while((b = fis.read()) != -1) { //字节输入流对象fis一次读一个字节 并赋值给b  判断b是不是-1
        System.out.println(b);  
    }
    fis.close();
    

    字节输出流 OutputStream:

    • OutputStream 是所有的字节输出流 的父类,它是一个抽象类。
    • ByteArrayOutputStreamFileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。
    • PipedOutputStream 是向与其它线程共用的管道中写入数据。
    • ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。
    FileOutputStream fos = new FileOutputStream("yyy.txt"); 
    fos.write(100);     //写出的是一个int数,但是到文件上的是一个字节,会自动去除前三个8位
    fos.write(99);      //此时文件yyy.txt中是 dc
    fos.close();
    

    注意:

    1)输出流输出数据在创建输出流对象的时候,如果不存在文件,就创建一个;如果存在就清空该文件数据,然后写入数据。
    2)如果想在文件里面追加写入就用new FileOutputStream(String pathName,true)这个构造方法。

    字符输入流:

    public int read():读取单个字符,并返回成int,如果已到达流的末尾,则返回 -1
    public int read(char[] cbuf):将字符读入数组,返回读取的字符数,如果已到达流的末尾,则返回 -1

    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("xxx.txt");  //创建字符输入流对象
        int c;
        
        while((c = fr.read()) != -1) {  //通过项目默认的码表一次读取一个字符
            System.out.print((char)c);  //将c强制类型转换成char
        }
        fr.close();
    }
    

    字符输出流:

    public void write(int c):写入单个字符。
    public void write(char[] cbuf):写入字符数组。
    public abstract void write(char[] cbuf,int off, int len):写入字符数组的某一部分。cbuf - 字符数组,off - 开始写入字符处的偏移量,len - 要写入的字符数。
    public void write(String str):写入字符串。
    public void write(String str,int off, int len):写入字符串的某一部分。str - 字符串,off - 相对初始写入字符的偏移量,len - 要写入的字符数 。

    节点流:
    直接与数据源相连,读入或读出。

    常用的节点流:

    • 父 类 :InputStreamOutputStreamReaderWriter
    • 文 件 :FileInputStreamFileOutputStreanFileReaderFileWriter 文件进行处理的节点流
    • 数 组 :ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
    • 字符串 :StringReaderStringWriter 对字符串进行处理的节点流
    • 管 道 :PipedInputStreamPipedOutputStreamPipedReaderPipedWriter 对管道进行处理的节点流

    处理流:
    处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流。

    常用的处理流:

    • 缓冲流:BufferedInputStreanBufferedOutputStreamBufferedReaderBufferedWriter 增加缓冲功能,避免频繁读写硬盘。
    • 转换流:InputStreamReaderOutputStreamReader实现字节流和字符流之间的转换。
    • 数据流: DataInputStreamDataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。

    转换流:
    InputStreamReaderOutputStreamWriterInputStreamOutputStream作为参数,实现从字节流到字符流的转换。

    序列流:
    序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推。

    1)整合两个输入流SequenceInputStream(InputStream s1, InputStream s2);

    public static void demo2() throws FileNotFoundException, IOException {
        FileInputStream fis1 = new FileInputStream("a.mp3");
        FileInputStream fis2 = new FileInputStream("b.mp3");
        SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
        FileOutputStream fos = new FileOutputStream("c.mp3");
        //歌曲串烧,c.mp3里面有a.mp3和b.mp3两首歌
    
        int b;
        while((b = sis.read()) != -1) {
            fos.write(b);
        }
    
        sis.close();        //sis在关闭的时候,会将构造方法中传入的流对象也都关闭
        fos.close();
    }
    

    2)整合多个输入流 SequenceInputStream(Enumeration<? extends InputStream> e)

    public static void main(String[] args) throws IOException {
    
        FileInputStream fis1 = new FileInputStream("a.txt");
        FileInputStream fis2 = new FileInputStream("b.txt");
        FileInputStream fis3 = new FileInputStream("c.txt");
    
        Vector<FileInputStream> v = new Vector<>();     //创建集合对象
        v.add(fis1);                        //将流对象存储进来
        v.add(fis2);
        v.add(fis3);
    
        Enumeration<FileInputStream> en = v.elements();
        SequenceInputStream sis = new SequenceInputStream(en);  //将枚举中的输入流整合成一个
        FileOutputStream fos = new FileOutputStream("d.txt");
    
        int b;
        while((b = sis.read()) != -1) {
            fos.write(b);
        }
    
        sis.close();
        fos.close();
    }
    

    相关文章

      网友评论

          本文标题:java IO流操作

          本文链接:https://www.haomeiwen.com/subject/efeaiktx.html