java基础 ---- FileOutputStream类, FileOutputStream类,FileReader类,FileWriter类

I/O流的理解概述:

  • I/O流:数据(文件,图片,视频等)以字节的形式存储,以流的形式在不同数据存储体间传输,以内存为基准可以将流的方向分为输入input输出output ,即流向内存是输入流,流出内存的输出流;按数据传输单位可以将流分为字节流,字符流。
  • 字节流与字符流:若文本文件含有多字节组成的字符时,应使用字符流读取文本。若使用字节流读取可能不会显示完整的字符,因为字节流每次只读取一个字节,只是完整字符的一部分。
    具体的:Java中的String类型默认就把字符以Unicode规则编码(一个字符对应两个字节)而后存储在内存中,字符流的读取单位就是一个Unicode码元。
  • java.io包中按照流划分角度的组合封装了四个顶级父类(选择抽象类而不是接口是因为若一个类同时实现输出流,输入流两个接口就会出错,而继承体系只能单继承),完成I/O操作,即输入、输出操作。输入也叫做读取数据,即从其他存储体对象读取数据到流中,流传输到内存中;输出也叫做作写出数据,即从内存写出数据到流中,流传输到其他存储体对象中。流对象在创建的时候就必须明确指向内存之外的另一存储体。
    输入流输出流
    字节流字节输入流InputStream字节输出流OutputStream
    字符流字符输入流Reader字符输出流Writer
  • 写出数据的原理:以内存-->硬盘为例
     java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据从内存写出到硬盘文件中(待写的数据就是写方法的参数)
  •  读取数据的原理:以硬盘-->内存为例
    java程序-->JVM-->OS-->OS读取数据的方法-->读取文件(硬盘-->内存)

FileStream的理解概述:

  • 以文件作为与内存进行数据传输的另一存储体,对应四种顶级父类分别有子类FileOutputStream,FileInputStream,FileReader,FileWriter。

FileStream的使用概述:

  • 四种顶级父类都定义了所有子类共有的基本方法,子类只需要创建对象,调用父类中的基本方法。

抽象类java.io.OutputStream中子类共有的成员方法:
-public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
-public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
-public void write(byte[] b):将字节数组从内存写出此输出流指向的文件。
-public void write(byte[] b, int off, int len) :把字节数组的一部分从内存写出到此输出流指向的文件。
int off:数组的开始索引
int len:写几个字节
-public abstract void write(int b) :将指定的字节从内存写出道此输出流指向的文件。int类型为4字节,即32个bit位,此处只写低8位

java.io.FileOutputStream 构造方法:
-public FileOutputStream(File file) :创建文件输出流对象并指向指定文件 即File对象。
-public FileOutputStream(String name) : 创建文件输出流对象并指向指定路径的文件
-public FileOutputStream(File file, boolean append) : 创建文件输出流指向指定文件,并设置是否清空原有内容。
-public FileOutputStream(String name, boolean append) : 创建文件输出流指向指定路径的文件,并设置是否清空原有内容。 

  

抽象类java.io.InputStream中子类共有的成员方法:
 -public abstract int read()从输入流中读取数据的下一个字节。
 -public int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
 -public void close() 关闭此输入流并释放与该流关联的所有系统资源。

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

抽象类 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() 关闭此流,但要先刷新它。

 FileWriter的构造方法:
-FileWriter(File file): 根据给定的 File 对象构造一个 FileWriter 对象。
-FileWriter(String fileName): 根据给定的文件名构造一个 FileWriter 对象。
-FileWriter(String fileName, boolean append)
-FileWriter(File file, boolean append)
 参数:
      String fileName,File file:写入数据的目的地
      boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写; false:创建新的文件覆盖源文件

抽象类 java.io.Reader中子类共有的成员方法:
-int read() 读取单个字符并返回。
-int read(char[] cbuf)一次读取多个字符,将字符读入数组。
-void close() 关闭该流并释放与之关联的所有资源。  

 FileReader的构造方法:
-FileReader(String fileName)
-FileReader(File file)
 参数:读取文件的数据源
     String fileName:文件的路径
     File file:一个文件


FileOutputStream的测试代码(整体阅读,局部运行):

/**运行前提:
 *1. import...
 */
public class FileOutputStreamTest throws IOException  {
    public static void main(String[] args) throws IOException {
       show1();
       show2();
    }

/**show1():通过FileOutputStream将内存中的内容写进硬盘的文件里
*1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
*2.调用FileOutputStream对象中的方法write,把数据写入到文件中
*3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
*/
    static void show1() throws IOException {
        //1. 
        /*  构造方法的作用:
            1.创建一个FileOutputStream对象
            2.会根据构造方法中传递的文件/文件路径,创建一个空的文件,注意不会创建文件夹
            3.会把FileOutputStream对象指向创建好的文件
        */        
        FileOutputStream fos = new FileOutputStream("MyTest\\a.txt");//创建一个向指定文件路径中写入数据的输出文件流
       //FileOutputStream fos = new FileOutputStream(new File("MyTest\\b.txt"));  创建一个向指定 File 对象表示的文件(注意:不是文件路径)中写入数据的文件输出流。
  
        //2.
        //写数据到硬盘文件时,会把10进制的整数转换为二进制存储(8个bit位),但是记事本打开文件时会查询编码表将字节转换为字符表示,0-127会查询ASCII表,其他值会查询系统默认码表(中文系统GBK)
        fos.write(97);//a
        //
        //white(int)只能写入一个字节,若在文件中显示100,需要写3个字节
        fos.write(49);//1
        fos.write(48);//0
        fos.write(48);//0
        //
        /*
        一次写多个字节:
          如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
          如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
         */
        //使用数组读取,每次读取多个字节,减少了系统间的IO操作次数,从而提高了读写的效率,建议开发中使用
        byte[] bytes = {65,66,67,68,69};//ABCDE
        //byte[] bytes = {-65,-66,-67,68,69};//烤紻E
        fos.write(bytes);
        //
        fos.write(bytes,1,2);//BC,从bytes数组索引为1的位置写入2个字节到文件中
        //
         /*
            写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组
                byte[] getBytes()  把字符串转换为字节数组
         */
        byte[] bytes2 = "你好".getBytes();
        System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67]
        fos.write(bytes2);  
       
        //3.
        fos.close();
       }


    /**show2():
     *1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地和追加写开关
     *2.调用FileOutputStream对象中的方法write,把数据写入到文件中
     *3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
     */
     static void show2() throws IOException {
      //1.         
        FileOutputStream fos = new FileOutputStream("MyTest\\c.txt",true); //true:追加数据
        //FileOutputStream fos = new FileOutputStream("MyTest\\c.txt",false); false:清空原有数据
        
      //2.
            for (int i = 1; i <=10 ; i++) {
            fos.write("你好".getBytes()); 
            //
            //windows:\r\n 为换行符号,转成byte[]数组写
            fos.write("\r\n".getBytes());
        }

      //3.流操作完毕后,必须释放系统资源,调用close方法
        fos.close();
    }
}

FileInputStream的测试代码(整体阅读,局部运行)

/**整体阅读,局部运行
 * 1.import ...
 * 2.项目文件夹里有MyTest//c.txt文件
 */
    
public class InputStreamTest {
    public static void main(String[] args) throws IOException {
        show1();
        show2();
   }
  /**show1():从文件中读取单个字节
   * 1.创建FileInputStream对象,构造方法中绑定要读取的数据源
   * 2.使用FileInputStream对象中的方法read,读取文件
   * 3.释放资源
   */
   static void show1() throws IOException {  
        //1.
        /* 构造方法的作用:
            1.会创建一个FileInputStream对象
            2.会把FileInputStream对象指向构造方法中要读取的文件的第一个字节
         */
        FileInputStream fis = new FileInputStream("MyTest\\c.txt"); //文件内容为abc
        //FileInputStream fis = new FileInputStream(new File("MyTest\\c.txt"));
        
        //2.int read()通过JVM,再通过OS,读取文件中的指针指向的字节并提升到int返回,连续读取时指针依次向后移,读取到文件的末尾返回-1
        int len = fis.read();
        System.out.println(len);//97 
        len = fis.read();
        System.out.println(len);// 98 
        len = fis.read();
        System.out.println(len);//99 
        len = fis.read();
        System.out.println(len);//-1
       /*
        int len = 0; //记录读取到的字节
        while((len = fis.read())!=-1){
            System.out.print((char)len);//abc
        }
        */

        //3.
        fis.close();
    }

   /**show2():从文件中读取字节数组
    *1.创建FileInputStream对象,构造方法中绑定要读取的数据源
    *2.使用FileInputStream对象中的方法read读取文件
    *3.关闭资源
    */
    public void show2() throws IOException {
        //1.
        FileInputStream fis = new FileInputStream("MyTest\\b.txt");//文件内容为ABCDE
        
        //2.
        //int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
        byte[] bytes = new byte[2]; // byte[]起到缓冲作用,存储每次读取到的多个字节,数组的长度一把定义为1024(1kb)或者1024的整数倍
        //
        //不同于读取单个字节int len记录每次读取的有效字节个数
        int len = fis.read(bytes); 
        System.out.println(len);//2
        //System.out.println(Arrays.toString(bytes));//[65, 66]
        /
        //String(byte[] bytes) :把字节数组转换为字符串
        System.out.println(new String(bytes));//AB
        len = fis.read(bytes);
        System.out.println(len);//2
        System.out.println(new String(bytes));//CD
        len = fis.read(bytes);
        System.out.println(len);//1
        //
        //String(byte[] bytes, int offset, int length) 把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数
        System.out.println(new String(bytes,0,len));//E
        //System.out.println(new String(bytes)); ED 错于当缓冲数组容量大于剩余字节时,上次读取的数据没有被完全替换而重复读取,所以要通过 len ,获取有效的字节.
        len = fis.read(bytes);
        System.out.println(len);//-1       
        /*
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = fis.read(bytes))!=-1){
            //
            //当数组容量大于读取内容时,直接转换成字符串会生成大量空格,所以只转换有效字节
            System.out.println(new String(bytes,0,len));
        }
        */

        //3.
        fis.close();
    }
}

 FileWrite的测试代码(整体阅读,局部运行)

/**运行前提:
 *1.import...
 *2.项目文件夹下备有作参数的文件夹,文件
 */

public class WriterTest {
    public static void main(String[] args) throws IOException {
        show1();
    }

   /**show1():
    * 1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
    * 2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
    * 3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
    * 4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
    */
   static void show1() throws IOException{
        //1.
         /*
           构造方法的作用:
            1.会创建一个FileWriter对象
            2.会根据构造方法中传递的文件/文件的路径,创建文件
            3.会把FileWriter对象指向创建好的文件
         */
        FileWriter fw = new FileWriter("MyTest\\e.txt");
        //FileWriter fw = new FileWriter(new File("MyTest\\e.txt"));
        //FileWriter("MyTest\\e.txt", true); append:true 不会创建新的文件覆盖源文件
        //FileWriter("MyTest\\e.txt", false);  append:false 会创建新的文件覆盖源文件

        //2.
        //write(int c)写入单个字符。
        fw.write(97);  
        fw.write("\r\n"); //windows换行符:\r\n

        //write(char[] cbuf)写入字符数组。
        char[] cs = {'a','b','c','d','e'};
        fw.write(cs);//abcde
        fw.write("\r\n");
        
        //void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
        fw.write(cs,1,3);//bcd
        fw.write("\r\n");

        //void write(String str)写入字符串。
        fw.write("你好世界");//你好世界
        fw.write("\r\n");

        //void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
        fw.write("你好世界",0,2);//你好
        fw.write("\r\n");

        //3. 刷新之后流可以继续使用
        fw.flush();       
        fw.write(98);

        //4.先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
        fw.close();
        fw.write(99);//IOException: Stream closed
    }
}

FilerReader的测试代码(整体阅读,局部运行):

public class ReaderTest {
    public static void main(String[] args) throws IOException {
        show1(); 
    }
    /**show1():
     * 1.创建FileReader对象,构造方法中绑定要读取的数据源
     * 2.使用FileReader对象中的方法read读取文件
     * 3.释放资源
     */
    static void show1(){
        //1.
        /*
         FileReader构造方法的作用:
         1.创建一个FileReader对象
         2.会把FileReader对象指向要读取的文件
         */
        FileReader fr = new FileReader("MyTest\\c.txt");
        //FileReader fr = new FileReader(new File("MyTest\\c.txt"));

        //2.
        //int read() 读取单个字符并返回。
        int len = 0;
        while((len = fr.read())!=-1){
            System.out.print((char)len);
        } 

        //int read(char[] cbuf)一次读取多个字符,将字符读入数组。
        char[] cs = new char[1024];//存储读取到的多个字符
        int len = 0;//记录的是每次读取的有效字符个数
        while((len = fr.read(cs))!=-1){
        System.out.println(new String(cs,0,len));
        }
  
        //3.
        fr.close();
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值