0
点赞
收藏
分享

微信扫一扫

Java之IO流技术详解

河南妞 2022-04-13 阅读 127
java后端

何为IO?

首先,我们看看百度给出的解释。

I/O输入/输出(Input/Output),分为IO设备和IO接口两个部分。

i是写入,Input的首字母。o是输出,Output的首字母。

IO分类

IO流主要分为两大类,字节流字符流。而按照作用分类,可以分为输入流输出流

流?

我们可以将这个整个看成一个水池。水池里面连接了出水口管与注水管。出水相当于我们的输出流。注水相当于我们的输入流。

File(文件类)

首先我们如果需要用IO流的话,我们肯定是需要创建一个我们所谓的**“水池”**的。

怎么创建呢?我们直接创建一个File类对象。

package IoDemo;
import java.io.*;
public class IoDemo {
    public static void main(String[] args) {
        //创建File对象
        File file  = new File("D:\\test.txt");
    }
}

实际上这个对象,说白了就是用来储存一个IO流的文件地址的。

创建了对象后,它也没有任何什么操作,操作得使用这个对象调用方法。

我们先使用createNewFile()方法创建我们上面那个路径的文件。

file.createNewFile();

注意定义文件路径时,可以用“/”或者“\”。

并且在创建一个文件时,如果目录下有同名文件将被覆盖。

因为有时候,可能我们的路径下已经存在了相对应的同名文件,所以我们要使用exists()方法判断文件是否已经存在。

 		//创建File对象
        File file  = new File("D:\\test.txt");
        //创建文件
        try {
            //判断文件是否存在
            if(!file.exists()){
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

其实,File类里面还存在许多方法,用法都是可以直接调用的,作为一个合格的程序员,我们可以直接阅读相关说明而在合适的时候使用对应方法

下面列举一些常用方法。

字节流的使用

我们现在已经建好这个**“水池”了,同时还可以使用方法来获取到“水池”**的一些信息。

那接下来,我们可以试着创建一套

字节流,相当于一滴滴的水在一个管道里运输。这个管道我们可以抽象的称之为流。

我们还是先看看知乎上,某些大佬的解释。

大佬的解释

  • 对于不完全学透的看法

    听起来有些难度哈,这些高级用法我们先不管。我们先来看看它到底怎么用的。

    OutputStream(字节输出流)

    !!!这里的输出可不是我们正常的输出,它反而想法,是将字节写入到文件,可以理解为将字节输出到文件。

    看看里面有些啥常用方法。

    我们先演示一下,字节输出流如何使用?

    //定义一个String值
    String str = "Hello World";
    

    等下我们利用字节流将这个String写入我们的文件里面。

    等等!这里是字节流,我怎么可以直接写入**String**?

    //将String值转换成字节数组
    byte[] bytes = str.getBytes();
    

    整个代码是这样的:

    package IoDemo;
    import java.io.*;
    public class IoDemo {
        public static void main(String[] args) {
            //创建File对象
            File file  = new File("D:\\test.txt");
            //创建文件
            try {
                //判断文件是否存在
                if(!file.exists()){
                    file.createNewFile();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //定义一个String值
            String str = "Hello World";
    
            //创建字节流
            FileOutputStream fos = null;
            try {
                //将File对象(即地址)给到FileInputStream
                fos = new FileOutputStream(file);
                //将String值转换成字节数组
                byte[] bytes = str.getBytes();
                //循环将字节数组写入到文件中
                for (int i = 0; i < bytes.length; i++) {
                    //将bytes写入文件
                    fos.write(bytes[i]);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    我们进我们的文件看看输出效果。

    就已经写入了我们的String里面的内容了。

    InputStream(字节输入流)

    //创建字节输入流
    FileInputStream fis = null;
    try {
        //将File对象(即地址)给到FileInputStream
        fis = new FileInputStream(file);
        //创建字节数组
        byte[] bytes = new byte[1024];
        //输出字节数组
        int len = 0;
        while ((len = fis.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, len));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    

    在上文,我们已经写入了一个Hello Word

    我们现在这段代码,我们将会输出文件中的内容。

    len = fis.read(bytes)) != -1
    

    我现在还是先讲解一下这一段。

    而我们字节流呢,一般是用于读取二进制文件,如音频、图片这些,大片的文字内容还是交给字符流吧。

    字符流的使用

    上面的字节流,它是一个个的输出的,而我们现在的字符流,是大水管输出,一次可以运输一段。

    FileWriter(字符输出流)

    老规矩哈,方法自己看看。

    先写入一个String试试。

    package IoDemo;
    import java.io.*;
    public class IoDemo {
        public static void main(String[] args) {
            String str = "嘿嘿!我是字符流·········";
            //创建File对象
            File file  = new File("D:\\test.txt");
            try {
                //将str用writer写入文件
                FileWriter fw = new FileWriter(file);
                fw.write(str);
                //关闭流,字符流必须关闭流才可以输出
                fw.close();
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    写入效果如下:

    实际上,写入字符串就几个步骤。

                //1.将str用writer写入文件
                FileWriter fw = new FileWriter(file);
                //2.使用write()方法写入字符串
                fw.write(str);
                //3.关闭流,字符流必须关闭流才可以输出
                fw.close();
    

    FileReader(字符输出流)

    		//输出文件内容
            try {
                //创建输入字符流
                FileReader fr = new FileReader(file);
                //输出文件内容
                int ch = 0;
                while ((ch = fr.read()) != -1){
                    System.out.print((char)ch);
                }
                //关闭流
                fr.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }	
    

    包装流

    缓冲流

    为什么使用缓冲流呢?

    缓冲流,也叫高效流。 能够高效读写缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化对象等等。 它是四个基本File流的增强,所以也是4个流,按照数据类型分类。 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO读取次数,从而提高读写的效率。

    package IoDemo;
    import java.io.*;
    public class IoDemo {
        public static void main(String[] args) {
            //创建File对象
            File file  = new File("D:\\test.txt");
            //创建缓冲流
            BufferedWriter bw = null;
            try {
                //创建FileWriter对象
                FileWriter fw = new FileWriter(file);
                //创建BufferedWriter对象
                bw = new BufferedWriter(fw);
                //写入一首诗分四次写入
                bw.write("窗前明月光,");
                bw.write("疑是地上霜。");
                bw.write("举头望明月,");
                bw.write("低头思故乡。");
                bw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    这个很简单,自己看就可以看懂。

    转换流

    我就不写示范了,网上找了一段。

            //转换流实现将 a.txt 文件 复制到 b.txt 中
    
            //1、创建源和目标
            File srcFile = new File("io"+File.separator+"a.txt");
            File descFile = new File("io"+File.separator+"b.txt");
            //2、创建字节输入输出流对象
            InputStream in = new FileInputStream(srcFile);
            OutputStream out = new FileOutputStream(descFile);
            //3、创建转换输入输出对象
            Reader rd = new InputStreamReader(in);
            Writer wt = new OutputStreamWriter(out);
            //3、读取和写入操作
            char[] buffer = new char[10];//创建一个容量为 10 的字符数组,存储已经读取的数据
            int len = -1;//表示已经读取了多少个字符,如果是 -1,表示已经读取到文件的末尾
            while((len=rd.read(buffer))!=-1){
                wt.write(buffer, 0, len);
            }
            //4、关闭流资源
            rd.close();
            wt.close();
    
    

    扩展

    然后,找相关资料时,还涨了个知识。大家可以看看。

    合并流

    合并流:把多个输入流合并为一个流,也叫顺序流,因为在读取的时候是先读第一个,读完了在读下面一个流。

     	    SequenceInputStream seinput = new SequenceInputStream();
            new FileInputStream("io/1.txt"), new FileInputStream("io/2.txt"));
            byte[] buffer = new byte[10];
            int len = -1;
            while((len=seinput.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
            }
            seinput.close();
    

    这里先是创建了一个SequenceInputStream对象,然后new了两个FileInputStream对象,我们使用合并流读取,先使用**seinput.read方法**读取1.txt的内容,然后再对其2.txt的内容。

    举报

    相关推荐

    0 条评论