Java学习笔记——IO

IO概述

生活中,肯定经理过这杨的场景,当你编辑一个文本文件,忘记了ctrl+s,可能文件就白白编辑了,当你电脑插入一个u盘,可以把一个视频拷贝到你的电脑硬盘中,那么数据是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等,我们把这种数据的传输,可以看作是数据的一种流动,按照流动的方向,以内存为基准,分为输入和输出,即流向内存的是输入流,流出内存的是输出流。

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

io的分类

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

​       输入流:把数据从其他设备上读取到内存中的流

​       输出流:把数据从内存写出到其他设备上的流

   根据数据的类型分类:字节流和字符流

​       字节流:以字节为单位,读写数据的流

​       字符流:以字符为单位,读写数据的流

顶级父类
输入流输出流
字节流字节输入流InputStream字节输出流OutputStream
字符流字符输入流Reader字符输出流Writer

字节流

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


字节输出流OutputStream

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

  public void close() 关闭此输出流并释放与此流相关的任何系统资源

  public void flush() 刷新此输出流并强制任何缓冲的输出字节被写出

  public void write(byte[] b) 将b.lengh个字节从指定的字节数组写如此输出流

  public void write(byte[] b,int off,int len) 从指定的字节数组写入len字节,从偏移量off开始输出到此输出流

  public void write(int b) 将指定的字节写入输出流

FileOutputStream类

  OutputStream有很多子类,java.io.FileOutputStream类是文件输出流,用于将数据写出到文件。

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

public class FileOutputStreamConstructor {
    public static void main(String[] args) throws FileNotFoundException {
        //使用File对象创建流对象
        File file = new File("d:\\a.txt");
        FileOutputStream fos = new FileOutputStream(file);
        //使用文件名创建流对象
        FileOutputStream fos2 = new FileOutputStream("d:\\a.txt");
    }
}
写出字节数据

   1.写出字节, write(int b) 每次可以写出一个字节数据

public class FileOutputStreamConstructor {
    public static void main(String[] args) throws IOException {
        //使用File创建流对象
        File file = new File("d:\\a.txt");
        FileOutputStream fos = new FileOutputStream(file);
        //使用文件名创建流对象
        FileOutputStream fos2 = new FileOutputStream("d:\\a.txt");
        //写出数据
        fos.write(97);
        fos.write(98);
        fos.write(99);
        //关闭资源
        fos.close();
    }
}

  2.写出字节数组,write(byte[] b) 每次可以写出数组中的数据

    public static void main(String[] args) throws IOException {
        //使用文件名来创建流对象
        FileOutputStream fos = new FileOutputStream("D:\\a.txt");
        //字符串转为字节数组 
        byte[] b = "Good Good Study".getBytes();
        //写出字节数组数据
        fos.write(b);
        //关闭资源
        fos.close();
    }
}

3.写出指定长度字节数组,write(byte[] b,int off,int len) 每次写出从off索引开始,len个字节

    public static void main(String[] args) throws IOException {
        //使用文件名来创建流对象
        FileOutputStream fos = new FileOutputStream("D:\\a.txt");
        //字符串转为字节数组
        byte[] b = "day day up".getBytes();
        //写出字节数组数据
        fos.write(b,2,2);
        //关闭资源
        fos.close();
    }
}

  数据追加续写

     经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据,如何保留目标文件中的数据,还能继续添加新的数据呢?

 public FileOutputStream(File file,boolean append) 创建文件输出流以写入由file指定的对象表示的文件

  public FileOutputStream(String name,boolean append) 创建文件输出流以写入指定的名称文件

  这两个构造方法,参数中要传入一个boolean类型的值,true表示追加数据,false表示清空原有数据,这样创建的输出流对象,就可以指定是否追加续写了

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\a.txt",true);
        //字符串转为字节数组
        byte[] b = "day day up".getBytes();
        //写出字节数组数据
        fos.write(b,2,2);
        //关闭资源
        fos.close();
    }
}

   写出换行

​     windows系统里,换行符是\r\n,以指定是否换行

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        //使用文件名来创建流对象
        FileOutputStream fos = new FileOutputStream("D:\\a.txt");
        //定义字节数组
        byte[] b = {97,98,99,100};
        //遍历数组
        for(int i=0;i<b.length;i++){
            //写出一个字节
            fos.write(b[i]);
            //写出换行 换行符符号转成数组写出
            fos.write("\r\n".getBytes());
        }
        //关闭资源
        fos.close();
    }
}
注意:

   回车符\r 和换行符 \n

​      回车符:回到一行的开头 

​      换行符:下一行

系统中的换行符: 

​     windows系统里,每行结尾都是回车+换行  \r\n

​     Linux系统里,每行结尾只有换行  \n

​     Mac系统里,每行结尾都是回车 \r 从Mac OS X开始于Linux统一

FileInputStream类

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

   public void close() 关闭此输入流并释放与此流相关的系统资源

   public abstract int read() 从输入流读取数据的下一个字节

   public int read(byte[] b) 从输入流中读取一些字节数,并将他们存储到字节数组中

   该类为文件输入流,从文件中读取字节数据

构造方法

​    FileInputStream(File file) 通过打开实际文件的连接来创建一个FileInputStream,该文件由系统中的file对象指定

​    FileInputStream(String name) 通过打开实际文件的连接来创建一个FileInputStream,该文件由路径名name指定。

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

public class FileInputStreamConstructor {
    public static void main(String[] args) throws FileNotFoundException {
        //使用file对象创建流对象
        File file = new File("d:\\a.txt");
        FileInputStream fis = new FileInputStream(file);
        //使用文件名构建流对象
        FileInputStream fis2 = new FileInputStream("d:\\a.txt")
    }
}

  读取字节数据

    1.读取字节:read() 方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1

public class FileInputStreamConstructor {
    public static void main(String[] args) throws IOException {
        //使用file对象创建流对象
        File file = new File("d:\\a.txt");
        FileInputStream fis = new FileInputStream(file);
        //使用文件名构建流对象
        FileInputStream fis2 = new FileInputStream("d:\\a.txt");
        //读取数据 返回一个字节
        int b;
        //循环读取
        while((b=fis.read())!=-1){
            System.out.println((char)b);
        }
        //关闭资源
        fis.close();
    }
}

    2.使用字节数组读取  read(byte[] b) 每次读取b个长度字节到数组中,返回读取到的有效字节个数,读到末尾,返回-1

public class FISRead {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileInputStream fis = new FileInputStream("d:\\a.txt");  //aabbccd
        //定义变量,作为有效个数
        int len;
        //定义字节数组,作为装字节数据的容器
        byte[] b = new byte[2];
        //循环读取
        while ((len=fis.read(b))!=-1){
            System.out.print((new String(b)));
        }
        //关闭资源
        fis.close();
    }
}
//输出结果 aabbccdc


发现错误数 c,是由于最后一次读取时,只读取了一个字节,数组中,上次读取的数据没有被完全替换,所以要通过len,获取有效的字节

修改代码:

public class FISRead {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileInputStream fis = new FileInputStream("d:\\a.txt");
        //定义变量,作为有效个数
        int len;
        //定义字节数组,作为装字节数据的容器
        byte[] b = new byte[2];
        //循环读取
        while ((len=fis.read(b))!=-1){
            System.out.print((new String(b,0,len)));
        }
        //关闭资源
        fis.close();
    }
}

字符流

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

字符输入流Reader

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

   public void close() 关闭此流并释放此流相关的任何系统资源

   public int read() 从输入流读取一个字符

   public int read(char[] chars) 从输入流中读取一些字符,并将他们存储到字符数组中

FileReader类

   该类是读取字符文件的便利类,构造时使用系统默认的字符集和默认的字节缓冲区

  注意:

​     1.字符编码,字节与字符的对应规则,windows系统的中文编码默认的是GBK编码表,idea中使用的是utf-8

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

构造方法:

   FileReader(File file) 创建一个新的FileReader,给定要读取的file对象

   FileReader(String fileName) 创建一个新的FileReader,给定要读取的文件的名称
 

 public static void main(String[] args) throws FileNotFoundException {
        //创建file对象
        File file = new File("D:\\a.txt");
        FileReader fr = new FileReader(file);
        //通过文件名创建
        FileReader fr2 = new FileReader("D:\\a.txt");
    }
}
读取字符数据

     1.读取字符  read() 每次读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取

public class FileReaderDemo {
    public static void main(String[] args) throws IOException {
        //创建file对象
        File file = new File("D:\\a.txt");
        FileReader fr = new FileReader(file);
        //通过文件名创建
        FileReader fr2 = new FileReader("D:\\a.txt");
        //定义变量保存数据
        int b;
        //循环获取
        while ((b=fr.read())!=-1){
            System.out.println((char)b);
        }
        fs.close;
    }
}

  2.读取字符数组  read(char[] chars) 每次读取数组长度个字符到数组中,返回读取到的有效个数,读取到文件末尾返回-1

public class FileReaderDemo {
    public static void main(String[] args) throws IOException {
        //创建file对象
        File file = new File("D:\\a.txt");
        FileReader fr = new FileReader(file);
        //通过文件名创建
        FileReader fr2 = new FileReader("D:\\a.txt");
        //定义变量保存数据
        int b2;
        int b;
        //定义数组
        char[] chars = new char[3];
        //循环获取
        while ((b=fr.read())!=-1){
            System.out.println((char)b);
        }
        //循环读取
        while ((b2=fr2.read())!=-1){
            System.out.println(new String(chars,0,b2));
        }
        fr.close;
        fr2.close;

    }
}
注意:

   读取数组时注意有效个数,参考字节输入流的讲解。


字符输出流Writer

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

  public void close() 关闭此流 之前要刷新

  public void write(int c) 写入单个字符

  public void write(char[] chars) 写入字符数组

  public void write(char[] chars,int off,int len) 写入字符数组的某一部分,off数组的索引开始,len写出的字符个数

  public void write(String str) 写入字符串

  public void write(String str, int off,int lent) 写入字符串的某一部分,off字符串索引开始,len写的字符个数

  public void flush() 刷新流


FileWriter类

  该类为写出字符到文件的便利类,构造是使用默认的系统字符编码和默认字节缓冲区

构造方法

​    FileWriter(File file)  创建一个FileWriter,给定要写入的file对象

​    FileWriter(String fileName) 创建一个FileWriter,给定要写入文件的名称

写出基本数据

​     1.写出字符  write(int b) 方法,每次可以写出一个字符数据,

public class FWWrite {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileWriter fw = new FileWriter("d:\\a.txt");
        //写出数据
        fw.write(97);
        fw.write('b');
        fw.write(3000);
        //关闭流
        fw.close();
    }
}

 

注意:

  关闭资源是,与FileOutputStream不同,如果不关闭,数据只是保存到缓冲区,并为保存到文件。

关闭和刷新:

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

​    flush: 刷新缓冲区,流对象可以继续使用

​    close:先刷新缓冲区,然同通知系统释放资源,流对象不可以再被使用了
 

public class FWWrite {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileWriter fw = new FileWriter("d:\\a.txt");
        //写出数据
        //写出数据
        fw.write('刷');
        fw.flush();
        fw.write('b');
        fw.write(3000);
        //关闭流
        fw.close();
        //关闭后再次调用流写数据
        fw.write(99);
    }
}

写出其他数据

   1.写出字符数组  write(char[] chars) 和 write(char[] chars,int off,int len)每次可以写出数组中的数据

public class FWWrite {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileWriter fw = new FileWriter("d:\\a.txt");
        //定义字符串数组
        char[] chars = "hello man".toCharArray();
        //写出数据
        fw.write(chars,2,2);
        //关闭流
        fw.close();

    }
}

 2.写出字符串  write(String stre) 和 write(String str,int off,int len) 每次可以写出指定字符串

public class FWWrite {
    public static void main(String[] args) throws IOException {
        //使用文件名创建流对象
        FileWriter fw = new FileWriter("d:\\a.txt");
        //定义字符串数组
        String str = "程序猿";
        //写出数据
        fw.write(str,2,1);
        //关闭流
        fw.close();

    }
}

注意:字符流,只能操作文本文件,不能操作图片、视频等非文本文件,当我们单纯读或者写文本文件的时候,使用字符流,其他情况使用字节流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值