Java IO流

目录

第一章 IO概述

1.1 什么是IO

1.2 IO的分类

1.3 顶级父类们

第二章  字节流

2.1 一切皆为字节

2.2 字节输出流【OutputStream】

2.3 FileOutputStream类

 2.4 字节输入流【InputStream】

 2.5 FilelnputStream类

 2.6 字节流练习: 复制

第三章 字符流

3.1字符输入流【Reader】

3.2 FileReader类

3.3 字符输出流【Writer】

3.4 FileWriter类

第四章 缓冲流


第一章 IO概述

1.1 什么是IO

生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s ,可能文件就白白编辑了。当你电脑上插入一个u盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和输output,即流向内存是输入流,流出内存的输出流。

Java中I/O操作主要是指使用 java.io 包下的内容,用于处理设备之间的数据传输输入也叫做读取数据,输出也叫做作写出数据,对于数据的输入/输出操作以“流(stream)的 方式进行。

1.2 IO的分类

根据数据的流向分为:输入流和输出流

  • 输入流input读取外部数据(磁盘、光盘等存储设备的数据)程序(内存)中的流。
  • 输出流output将程序(内存)数据输出到磁盘、光盘等存储设备中的流。
  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流

1.3 顶级父类们

 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

第二章  字节流

2.1 一切皆为字节

一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

2.2 字节输出流【OutputStream】

java.io.0utputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush() : 刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[] b) : 将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len) :从指定的字节数组写入len字节,从偏移量 off开始输出到此输出流。
  • public abstract void write(int b):将指定的字节输出流。
package com.hp.tset1;

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

public class FileOutPutStreamTest02 {
    public static void main(String[] args) throws IOException {
        /**
         * void write(int b) 一次写一个字节数据
         * void write(byte[] b) 一次写一个字节数组数据
         * void write(byte[] b, int off, int,len) 一次写一个字节数组的部分数据
         *  参数一:数组
         *  参数二:索引起始
         *  参数三:个数
         */

        //1.创建对象
        FileOutputStream fos = new FileOutputStream("io\\a.txt");
        //2.写出数据
        fos.write(97);//a  //按照ASCII解析数组 写入文件
        fos.write(98);//b

        byte[] b ={97,98,99,100,101};
        fos.write(b);//abcde

        fos.write(b,0,4); //abcd //数组,索引起始,个数

        //3.释放资源
        fos.close();

    }
}

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

2.3 FileOutputStream类

outputstream 有很多子类,我们从最简单的一个子类开始
java.io.FileOutputstream 类是文件输出流,用于将数据写出到文件。

构造方法

  • public Fileoutputstream(File file): 创建文件输出流以写入由指定的 File对象表示的文件。
  • public FileOutputstream(String name) : 创建文件输出流以指定的名称写入文件。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。

构造举例,代码如下:

package com.hp.tset1;

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

public class FileOutPutStreamTest01 {
    public static void main(String[] args) throws IOException {
        /**
         *      细节1: 参数是宁符串表示的路径或者是File对象都是可以的
         *      细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
         *      细节3:如果文件已存在,则会清空文件
         */


         //使用File对象创建流对象
         File file = new File("atxt"):
         FileOutputStream fos = new FileOutputStream(file);

      
        //使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("io\\a.txt");
    

        
    }
}

写出字节数据

写出字节 : write(int b) 方法,每次可以写出一个字节数据,代码使用演示 :

package com.hp.tset1;

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

public class FileOutPutStreamTest01 {
    public static void main(String[] args) throws IOException {

        //1.创建对象
        //写出一段文字 输出 FileOutputstream
        FileOutputStream fos = new FileOutputStream("io\\a.txt");
        //2.写出数据
        fos.write(98);//b
        //3.释放资源
        fos.close();//解除了资源的占用

        
    }
}

写出换行
Windows系统里,换行符号是r\n 。把以指定是否追加续写了,代码使用演示:

package com.hp.tset1;

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

public class FileOutPutStreamTest03 {
    public static void main(String[] args) throws IOException {
        /**
         * 换行写:
         *      再次写出一个换行符就可以了
         *      windows:  \r\n
         *      Linux:  \n
         *      Mac:   \r
         *  细节:
         *      在windows操作系统当中,java对回车换行进行了优化。虽然完整的是\r\n,
         *      但是我们写其中一个\r或者\n,java也可以实现换行,因为java在底层会补全。
         *  建议:
         *      不要省略,还是写全了。
         *  续写:
         *     如果想要续写,打开续写开关即可开关位置:创建对象的第二个参数默认false: 表示关闭续写,
         *     此时创建对象会清空文件手动传递true: 表示打开续写,
         *     此时创建对象不会清空文件
         */

        //1.创建对象
        FileOutputStream fos = new FileOutputStream("io\\a.txt",true);

        //2.写出数据
        String src1 = "yiyangqianxi";
        byte[] b1 = src1.getBytes();
//        System.out.println(Arrays.toString(b));
        fos.write(b1);

        String wrap = "\r\n";
        byte[] b2 = wrap.getBytes();
        fos.write(b2);

        String src2 = "999";
        byte[] b3 = src2.getBytes();
        fos.write(b3);


        //3.释放资源
        fos.close();
    }
}

 2.4 字节输入流【InputStream】

java,io.Inputstream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

  • public void close():关闭此输入流并释放与此流相关联的任何系统资源。
  • public abstract int read() : 从输入流读取数据的下一个字节。
  • public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组b中。

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

package com.hp.test1;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\chenge\\Desktop\\work\\a.txt");
        //read()读取一个字节,把当前字符转换成对应的整数返回,如果读取到文件末尾,则返回-1
        int read1 = fis.read();
        System.out.println(read1);//121

        int read2 = fis.read();
        System.out.println(read2);//121

        int read3 = fis.read();
        System.out.println(read3);//113

        int read4 = fis.read();
        System.out.println(read4);//120

        int read5 = fis.read();
        System.out.println(read5);//-1

        fis.close();
    }
}

 字节循环输出流

package com.hp.test1;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) throws IOException {
        //输出流: 把内容的内存输出到文件中(写操作)    输入流: 把文件的内容输入到内存中(读操作)
FileInputStream fis = new FileInputStream("C:\\Users\\chenge\\Desktop\\work\\a.txt");
      //字节循环输出流
       int len1;
        while ((len1 = fis.read()) != -1){
            System.out.println((char)len1);//强转
        }
        fis.close();

    }
}

 

 读取多个字节文件

package com.hp.test1;

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

public class FileInputStreamTest04 {
    public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\chenge\\Desktop\\work\\a.txt");
        byte[] bytes1 = new byte[8];
        int ab;
        while (( ab = fis.read(bytes1))!= -1){
                String str = new String(bytes1, 0, ab);
                System.out.println(str);
        }
        fis.close();
    }
}

 2.5 FilelnputStream类

java.io.FileInputstream 类是文件输入流,从文件中读取字节。

构造方法

  • FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FilelnputStream,该文件由文件系O统中的 File对象 file命名。
  • FileInputStream(String name) : 通过打开与实际文件的连接来创建一个FilelnputStream,该文件由文件系统中的路径名 name命名。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FleNotFoundException。

构造举例,代码如下 :

package com.hp.tset1;

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

public class FileInPutStreamTest01 {
    public static void main(String[] args) throws IOException {
      


         //使用File对象创建流对象
         File file = new File("a.txt"):
         FileInputStream fis = new FileInputStream(file);

      
        //使用文件名称创建流对象
        FileInputStream fis = new FileInputStream ("io\\a.txt");
    

        
    }
}

 2.6 字节流练习: 复制

原理:从已有文件中读取字节,将该字节写出到另一个文件中。

案例:文件的复制

我们把a.txt文件复制

package com.hp.test2;

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

public class copyTest01 {
    public static void main(String[] args) throws IOException {
        /**
         * 文件的复制
         */

        //定义输入输出流关联文件
FileInputStream fis = new FileInputStream("C:\\Users\\chenge\\Desktop\\work\\a.txt");

FileOutputStream fos = new FileOutputStream("C:\\Users\\chenge\\Desktop\\work\\c.txt");
        //使用缓冲区读写
        byte[] bytes = new byte[8];
        int aa;
        while ((aa = fis.read(bytes)) != -1){
           fos.write(bytes,0,aa);
       }
        //4.释放资源  先开的后关闭
        fos.close();
        fis.close();
    }
}

运行效果:

第三章 字符流

 当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为个中文字符可能占用多个字节存储。所以ava提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

3.1字符输入流【Reader】

java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

  • public void close():关闭此流并释放与此流相关联的任何系统资源
  • public int read() : 从输入流读取一个字符。
  • public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。
  • int read(char[] cbuf,int off,int len) : 将字符读入数组的某一部分。存到数组cbuf 中,从 off 处开始存储,最多读 len 个字符。如果已到达流的末尾,则返回 -1 。否则返回本次读取的字符数。
package com.hp.test1;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class ReaderTest01 {
    public static void main(String[] args) throws IOException {
        //1.定义字符输入流:在字节流汉字占三个字节,字符流中汉字占一个字符
        FileReader fr = new FileReader("C:\\Users\\chenge\\Desktop\\work\\a.txt");

        //每次读取一个字符
        int i1 = fr.read();
        System.out.println((char)i1);

        int i2= fr.read();
        System.out.println((char)i2);

        //每次读取缓冲区
        char[] chars = new char[3];
        int i1 = fr.read(chars);//每次至多读取数组长度个字符,把读取到字符存入数组中,返回的是实际读取的字符数
        String s1 = new String(chars,0,i1);//截收数组,从第0个索引,截取读收有效字符数长度
        System.out.println(s1);

        int i2 = fr.read(chars);//每次至多读取数组长度个字符,把读取到字符存入数组中,返回的是实际读取的字符数
        String s2= new String(chars,0,i2);
        System.out.println(s2);

        //3.释放资源
        fr.close();
    }
}

3.2 FileReader类

java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。 

1.字符编码: 字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。idea中UTF-8

2.字节缓冲区:一个字节数组,用来临时存储字节数据。

 构造方法

  • FileReader(File file) : 创建一个新的 FileReader,给定要读取的File对象。
  • FileReader(String fileName): 创建一个新的 FileReader,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径。类似于FilelnputStream 。

构造举例,代码如下:

public class FileReaderConstructor throws IOExceptionf{
public static void main(String[] args){
    // 使用File对象创建流对象
    File file = new File("a.txt");
    FileReader fr = new FileReader(file);

    //使用文件名称创建流对象
    FileReader fr = new FileReader("b,txt");
    
    }
}

3.3 字符输出流【Writer】

java.io.writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

  • void write(int c) 写入单个字符。
  • void write(char[] cbuf) 写入字符数组。
  • abstract void write(char[] cbuf,int off,int len) 写入字符数组的某一部分,off数组的开始索引len写的字符个数。
  • void write(String str) 写入字符串。
  • void write(String str,int off,int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
  • void flush()刷新该流的缓冲。
  • void close() 关闭此流,但要先刷新它。
package com.hp.test1;

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

public class WriterTest02 {
    public static void main(String[] args) throws IOException {
        File f1=new File("C:\\Users\\chenge\\Desktop\\work\\d.txt");
        if(!f1.exists()) {
            f1.createNewFile();
        }
        //1.定义字符输出流:
        FileWriter fw = new FileWriter(f1);

        //2.写出数据
        fw.write(97);

        fw.write((int)'我');

        char[] chars = {'易','烊','千','玺'};
        fw.write(chars,0,3);//索引0 取3个

        fw.write("姊姊,鑫鑫,玉玉");

        fw.flush();//字符流必须刷新缓冲区,才会真正写入磁盘文件中

        //3.释放资源
        fw.close();

    }
}

3.4 FileWriter类

java.io.FileNriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区构造方法。

  • Filewriter(File file) : 创建一个新的FileWriter,给定要读取的File对象。
  • FileWriter(String fileName): 创建一个新的FileWriter,给定要读取的文件的名称。
public class FileWriterConstructor throws IOExceptionf{
    public static void main(String[] args){
        // 使用File对象创建流对象
        File file = new File("a.txt");
        FileWriterfr = new FileWriter(file);

        //使用文件名称创建流对象
        FileWriterfr = new FileWriter("b,txt");
    
    }
}

续写和换行 : 操作类似于FileOutputStream。

    public class FWWrite {
        public static void main(String[] args) throws IOException {
            //使用文件名称创建流对象,可以续写数据
            Filewriter fw = new FileWriter("fw.txt" , true);
            // 写出字符串
            fw.write("姊姊");
            // 写出换行
            fw.write("\r\n");
            // 写出字符串
            fw,write("鑫鑫");
            // 关闭资源
            fw.close();

        }
}

关闭和刷新

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要 flush 方法了。

第四章 缓冲流

为了提高数据读写的速度 Java API 提供了带缓冲功能的流类,在使用这些流类
时,会创建一个内部缓冲区数组,缺省使用 8192 个字节 (8Kb) 的缓冲区

1.1 概述

缓冲流,也叫高效流,是 对4个基本的 Filexxx 流的增强,所以也是4个流,按照数据类型分类:
  • 字节缓冲流: BufferedInputStream BufferedOutputStream
  • 字符缓冲流 : BufferedReader Bufferedwriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统10次数,从而提高读写的效率。

1.2 字节缓冲流

构造方法
  • public BufferedInputStream(InputStream in) :创建一个新的缓冲输入流。
  • public Bufferedoutputstream(OutputStream out) : 创建一个新的缓冲输出流。

 构造举例,代码如下:

//创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("io\\a.txt"));
//创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("io\\bbb.txt"));
package com.hp.test5;

import java.io.*;

public class BufferedStreamTest01 {
    public static void main(String[] args) throws IOException {
        /**
         * 需求:
         *      利用字节缓冲流拷贝文件
         * 字节缓冲输入流的构造方法:
         *      public BufferedInputStream(InputStream is)
         * 字节缓冲输出流的构造方法:
         *      public BufferedOutputStream(OutputStream os)
         */

        //1.创建缓冲流的对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("io\\a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("io\\bbb.txt"));

        //2.循环读取并写到目的地
        int c;
        while ((c = bis.read()) != -1){
            bos.write(c);
        }

        //2.拷贝(一次读写多个字节)
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }


        //3.释放资源
        bos.close();
        bis.close();
    }
}

1.3字符缓冲流

构造方法

  • public BufferedReader(Reader in):创建一个新的缓冲输入流。
  • public BufferedWriter(writer out):创建一个新的缓冲输出流。

构造举例,代码如下:

//创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
//创建字符缓冲输出流
Bufferedwriter bw = new Bufferedwriter(new FileWriter("bw.txt"));

特有方法

字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法

  • BufferedReader: public String readLine():读一行文字。
  • BufferedWriter: public void newLine(): 写一行行分隔符,由系统属性定义符号。

readLine 方法演示,代码如下:

package com.hp.test5;

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

public class BufferedStreamTest03 {
    public static void main(String[] args) throws IOException {
        /**
         * 字符缓冲输入流:
         * 构造方法:
         *      public BufferedReader(Reader r)
         * 特有方法:
         *      public String readLine()读一整行
         */

        //1.创建字符缓冲输入流的对象
        BufferedReader br = new BufferedReader(new FileReader("io\\a.txt"));
        //2.读取数据
        //细节:
        //readLine方法在读取的时候,一次读一整行,遇到回车换行结束  但是他不会把回车换行读到内存当中
//        String s = br.readLine();
//        System.out.println(s);
//
//        String s2 = br.readLine();
//        System.out.println(s2);

        String lind;
        while ((lind = br.readLine()) != null){
            System.out.println(lind);
        }
        //3.释放资源
        br.close();

    }
}

newLine 方法演示,代码如下:

package com.hp.test5;

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

public class BufferedStreamTest04 {
    public static void main(String[] args) throws IOException {
        /**
         *字符缓冲输出流
         * 构造方法:
         *      public BufferedWriter(Writer r)
         * 特有方法:
         *      public void newLine()    跨平台的换行
         */

        //1.创建字符缓冲输出流
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt",true));
        //2.写出数据
        bw.write("易烊千玺");
        bw.newLine();//跨平台的换行
        bw.write("红海不倒,我们一直在");
        //3.释放资源
        bw.close();
    }
}
  • 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区。
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流。
  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流。
  • flush()方法的使用:手动将buffer中内容写入文件如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃汉堡的代码人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值