一篇快速理解JavaIO流

节点流

在这里讲一讲直接操作文件的节点流

抽象基类

节点流(文件流)

InputStream

FileInputStream

outputStream

FileOutputStream

Reader

FileReader

Writer

FileWriter

前置知识:java中IO流File类

FileInputStream 和FileOutputStream 分别是字节输入流字节输出流,一般用来处理非文本文件(.jpg,.mp4,.mp3,.abi,.doc,.ppt,…)

FileReader 和 FileWriter 分别是字符输入流字符输出流,更多的是用来处理文本文件(.txt,.java,.c,.cpp)的数据。

下面首先来介绍一下字符输入输出流来处理文本数据。

FileReader

 在我的工程下有一个helloworld.txt的文件并且里面写了内容。用流去读文件之前要确保文件存在
 对相对路径(文件位置)很迷的小伙伴可以用System.out.println(file.getAbsolutePath());来查看一下这个文件的绝对路径。

@Test
    public void FileReader() throws IOException {
        //实例化File对象,指明要操作的文件
        File file = new File("helloworld.txt");//相较于当前module

        //提供具体的流
        FileReader fr = new FileReader(file);

        //数据的读入
        //read():返回读入的一个字符,如果到达文件末尾则返回-1
        int data;
        while((data = fr.read()) != -1){
            System.out.print((char)data);
        }

        //流的关闭操作
        fr.close();
    }

注:一定要注意流的关闭,JVM垃圾回收机制对于物理连接,如数据库连接,输入输出流,Socket连接,无能为力。
 为了保证流资源一定能执行关闭操作,使用try-catch-finally处理。

@Test
    public void FileReader(){
        FileReader fr = null;
        try {
            //实例化File对象,指明要操作的文件
            File file = new File("helloworld.txt");//相较于当前module
            System.out.println(file.getAbsolutePath());

            //提供具体的流
            fr = new FileReader(file);

            //数据的读入
            //read():返回读入的一个字符,如果到达文件末尾则返回-1
            int data;
            while((data = fr.read()) != -1){
                System.out.print((char)data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //流的关闭操作
                if(fr != null) fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

read()方法操作升级,不再一个一个字符的读取,一次读入char[](多个)。在数据量大的情况下,这种方法效率明显更高。
代码如下:

@Test
    public void FileReader1(){
        FileReader fr = null;
        try {
            //实例化File对象,指明要操作的文件
            File file = new File("helloworld.txt");//相较于当前module
            System.out.println(file.getAbsolutePath());

            //提供具体的流
            fr = new FileReader(file);

            //数据的读入
            //read(char[] cbuf):返回每次读入到数组中的字符个数。如果达到文件末尾,返回-1.
            int data;
            char[] buffer = new char[1024];
            while((data = fr.read(buffer)) != -1){
                //取数据的时候注意,这里是data,不是buffer.length。原因嘛,自然是读多少个就取多少个,取多了自然就错了。
                System.out.println(new String(buffer,0,data));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //流的关闭操作
                if(fr != null) fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



FileWriter

  • 输出的操作,对应的File可以不存在。
    如果不存在,输出的过程中会创建此文件。
    如果存在,FileWriter fw = new FileWriter(file,true);true表示追加,如果不写true则默认false,默认对文件的覆盖。
@Test
    public void FileWriter() {
        FileWriter fw = null;
        try {
            //提供File对象,指明写入到的文件。
            File file = new File("hello1.txt");

            //提供FileWriter对象,用于数据的写出。
            fw = new FileWriter(file,true);

            //写入数据
            //write参数的数据类型多样,可以自己去看看源码,很多重载方法。
            fw.write("I hava a dream \n".toCharArray());
            fw.write("你呢");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //流的关闭
                if (fw != null) fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



FileInputStream & FileOutputStream

字符流更多的是用来处理文本文件(.txt,.java,.c,.cpp)的数据,如果用来处理非文本文件(.jpg,.mp4,.mp3,.abi,.doc,.ppt,…)的话就会出错,这个时候就需要字节流来处理了。同样的使用字节流去处理文本文件,也很容易出现乱码的现象。

下面用一个例子演示一下节点流中的字节流:
eg:把D:/团圆照.jpg (已经存在),这张d盘下的团圆照图片,复制(write)到F盘下,命名为:合家欢喜.jpg(还不存在):

@Test
    public void FileInputStreamTest(){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            //提供file对象
            File file1 = new File("D:\\团圆照.jpg");
            File file2 = new File("F:\\合家欢喜.jpg");

            //创建字节输入输出流
            fileInputStream = new FileInputStream(file1);
            fileOutputStream = new FileOutputStream(file2);
            //复制的过程
            int len;
            byte[] data = new byte[1024];
            while((len = fileInputStream.read(data)) != -1){
                fileOutputStream.write(data,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //流的关闭
            try {
                if(fileInputStream != null) fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fileOutputStream != null) fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }