IO流的基本操作

一、流是什么?

File中虽然能进行一些常规的文件操作,但是这里少了两个非常核心的操作,java中针对文件操作,又进行了进一步的抽象~。

流是一组类/API,描述了如何来进行文件读写操作。

  • 读文件
  • 写文件

二、IO流分类 

所有 IO流 相关的类,一共分为两大部分:

1.字节流 读写数据以字节为基本单位  字节(byte)。

2.字符流 读写数据以字符为基本单位  字符(char)。

处理文本文件/数据的时候,使用字符流。

处理二进制文件/数据的时候,使用字节流。

三、什么是文本文件?什么是二进制文件?

区分方式很简单:拿一个记事本打开这个文件。

里面的内容能看懂,就是文本文件。

里面的内容看不懂,就是二进制文件。

例如:

(a).docx(word文档)是文本文件,还是二进制文件?

        二进制文件

        虽然docx中主要内容是文本,但是由于要保存版式这样的基本信息,这些信息都是使用 二进制 的方式来保存的。

(b)excel创建的文件是文本文件还是二进制文件?

        xlsx格式是二进制文件。

        csv格式是文本文件。

四、字节流 和 字符流

  • 字节流

1.InputStream:输入  从输入设备读取数据到内存中

2.OutputStream:输出  把内存中的数据写入到输出设备中

如果发现某个类的名字中有InputStream或 OutputStream,说明这个类就是字符流~

  • 字符

1.Reader: 输入

2.Writer: 输出

  如果发现某个类的名字中有Reader 或 Writer,说明这个类就是字符流~

注意,此处有特例,InputStreamReader,OutputStreamWriter是字符流

这两个类能够把字节流转换为字符流~~

五、流对象的核心操作流程

流对象的核心操作主要有个:

1.打开文件(构造方法)

2.read : 从文件中把数据读取到内存中

3.write: 把数据从内存写入文件中

4.close: 关闭文件

如果不关闭文件资源,就会造成文件资源泄露。

文件资源泄露的关键在于,文件描述符表是有上限的。如果代码中一直在反复打开新的文件,而没有关闭的话,文件描述符表就会被打满,一旦满了之后,后面再想打开新的文件就会打开失败。

Reader和Writer基本操作:

package com.java.bite.Buffered_IO_Stream2;

import java.io.*;

/**
 * @program: IO
 * @description
 * @author: wenwen
 * @create: 2021-08-03 14:42
 **/
//字符流 和字节流
public class CharStreamAndbyteStream3 {
    private static void copyFile1(){
        //处理文本文件,需要使用字符流
        try(FileReader fileReader = new FileReader("d:/test_dir/新建文本文档.txt");
        FileWriter fileWriter = new FileWriter("d:/test_dir/copyFile1.txt")){
            char[] buffer = new char[1024];
            int len = -1;
            while((len = fileReader.read(buffer)) != -1){
                fileWriter.write(buffer,0,len);
            }

        }catch (IOException e){
            e.printStackTrace();
        }
    }
    private static void copyFile2(){

        try(BufferedReader bufferedReader = new BufferedReader(new FileReader("d:/test_dir/新建文本文档.txt"));
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:/test_dir/copyFile2.txt"))){
            char[] buffer = new char[1024];
            int len = -1;
            while((len = bufferedReader.read(buffer)) != -1){
                bufferedWriter.write(buffer,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    private static void copyFile3(){
    // 带缓冲区的字符流中有一种特殊的用法,按行读取
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader("d:/test_dir/新建文本文档.txt"));
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:/test_dir/copyFile3.txt"))){
           String line = "";
           //readLine 表示读一行,读到换行符位置,如果读取文件完毕,就会返回null
            while((line = bufferedReader.readLine()) != null){
                System.out.println("line:"+line);

                bufferedWriter.write(line + "\n");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
//        copyFile1();
//        copyFile2();
copyFile3();
    }

}

 FileInputStream和FileOutputStream基本操作

package com.java.bite.byteStream;

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

/**
 * @program: IO
 * @description
 * @author: wenwen
 * @create: 2021-08-03 11:25
 **/
public class IODemo3 {
    //当代码这样子的时候,就不需要显示调用close了
    //try 语句会在代码执行完毕后,自动调用close方法(前提是这个类必须实现 Closable 接口)
    private static void copyFiles(){
        try(FileInputStream fileInputStream = new FileInputStream("d:/test_dir/1.jgp");
            FileOutputStream fileOutputStream = new FileOutputStream("d:/test_dir/3.jpg")){
            byte[] buffer = new byte[1024];//这就是缓冲区
            int len = -1;
            while((len = fileInputStream.read(buffer)) != -1){
                fileOutputStream.write(buffer,0,len);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {


    }
}

六、类自带的缓冲区

BufferedInputStream

BufferedOutputStream

内置了缓冲区,=》本质上就是一块内存空间,缓冲区存在的意义就是为了提高程序的运行效率。

使用如下代码,测试带缓冲区和不带缓冲区的效率。

package com.java.bite.Buffered_IO_Stream2;

import java.io.*;

/**
 * @program: IO
 * @description
 * @author: wenwen
 * @create: 2021-08-03 13:55
 **/
//分别不使用缓冲区和使用缓冲区读取一个大文件~感受时间上的差异
public class IODemo2 {
    public static void main(String[] args) {
//    testNoBuffer();
    testBuffer();
    }
    private static void testNoBuffer(){
        //读的时候就是一个字节一个字节的读,完全不使用任何缓冲区
        long beg = System.currentTimeMillis();
        try(FileInputStream fileInputStream = new FileInputStream("d:/test_dir/一寸.jpg")){
            int ch = -1;
            while((ch = fileInputStream.read()) != -1){
                //啥都不干了
            }

        }catch (IOException e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("no buffer:"+(end - beg)+"ms");

    }
    private static void testBuffer(){
        long beg = System.currentTimeMillis();
        try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("d:/test_dir/一寸.jpg"));
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:/test_dir/4"))){
            int ch = -1;
            while((ch = bufferedInputStream.read()) != -1){

            }

        }catch(Exception e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("buffer"+(end - beg)+"ms");
    }
}

package com.java.bite.Buffered_IO_Stream2;

import java.io.*;

/**
 * @program: IO
 * @description
 * @author: wenwen
 * @create: 2021-08-03 12:59
 **/
//BufferedInputStream 和 BufferedOutputStream
public class BufferedIO {
    public static void copyFile1() throws IOException {
        //需要创建的实例是 BufferedInputStream 和 BufferedOutputStream
        //创建这样的实例,需要先创建 FileInputStream 和 FileOutputStream
        FileInputStream fileInputStream = new FileInputStream("d:/test_dir/1/1.jpg");
        FileOutputStream fileOutputStream = new FileOutputStream("d:/test_dir/2.jpg");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        byte[] buffer = new byte[1024];
        int len = -1;
        while((len = bufferedInputStream.read(buffer)) != -1){
            bufferedOutputStream.write(buffer,0,len);
        }
        // 此处涉及 四个流对象
        //调用一组 close 时候,就会自动关闭内部包含的 FileInputSteram 和 FileOutputStream
        //此处不需要写四次关闭
        bufferedInputStream.close();
        fileOutputStream.close();
        fileInputStream.close();//这不就相当于是调用了两次close吗?阅读源码发现,close关闭两次不会发生副作用


    }
    //通过try自动关闭
    private static void copyFile(){
        try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("d:/test_dir/1/1.jpg"));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:/test_dir/1/4.jpg"))
        ){
            int len = -1;
            byte[] buffer = new byte[1024];
//            while((len = bufferedInputStream.read(buffer)) != -1){
//                System.out.println(len);
//                bufferedOutputStream.write(buffer,0,len);
//            }
            while(true){
                if(len == -1){
                    break;
                }
                bufferedOutputStream.write(buffer,0,len);
            }



        }catch(IOException e){
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
    copyFile();
    }
}

细节:

字节流的读写以byte为单位,缓冲区就是一个byte[]

字符流的读写以char为单位,缓冲区就是一个char[]

字符流可以使用readLine读取一行数据, readLine 读到的一行数据,会自动把最末尾的换行符去掉,把内容写入文件的时候,如果想换行,就需要手动添加一个换行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值