IO的读写文件操作及其注意事项

什么是流

在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。

流的分类

字节流与字符流
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。(这四个都是抽象类)

FileInputStream和FileOutputStream

方式一:通过字节数组来读取

public static void readAndWriteFileByBytes(String path) {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(path.toString());
            out = new FileOutputStream("E://abc//c.jpg");
            byte[] buf = new byte[1024*1];
            int len = 0;
            while ((len =in.read(buf))!=-1) {
                out.write(buf, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out!=null || in!=null){
                try {
                    out.close();
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        out=null; //去除引用,这样处理可以加快清理的速度
        in=null;
    }

报错:

java.io.FileNotFoundException: E:\abc (拒绝访问。)

out = new FileOutputStream(“E://abc//c.jpg”) 输出的位置,这里有一个我自己认为的坑,当时我懵逼了,就是输出到这个目录下啊,怎么报错了呢,查了很多资料才发现,输出的是一个具体的路径,也就是到哪个文件。(我自己的理解:输出是以流的形式输出的,肯定要有相应的同种类型的文件接受流才对)
out = new FileOutputStream(“E://abc//c.jpg”) 这样就没有问题啦,

方式二: 一个一个字节的读取

public static void readAndWriteFileByByte(String path) throws IOException {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        FileOutputStream out = new FileOutputStream("E:/abc/a.jpg");
        int len = 0;
        while ((len = in.read()) != -1){
            out.write(len);
        }
        in.close();
        out.close();
    }
    

BufferedInputStream和BufferedOutputStream

方式一: 一个一个字节的读取

public static void readAndWriteFileByBufferedOutputStream(File file) throws IOException {
        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
        //byte[] buffer = new byte[1024];
        int read = 0;
        while ((read = inputStream.read())!=-1){
            System.out.println(read);
            //outputStream.write(buffer,0,read);
            outputStream.write(read);
            //outputStream.flush();//刷新此缓冲的输出流。这将强制将任何缓冲的输出字节写出到基础输出流。
        }
        inputStream.close();
        outputStream.close();
    }

方式二:通过字节数组来读取

public static void readAndWriteFileByBufferedOutputStream(File file) throws IOException {
        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
        byte[] buffer = new byte[1024];
        int read = 0;
        while ((read = inputStream.read(buffer))!=-1){
            System.out.println(read);
            outputStream.write(buffer,0,read);
        }
        inputStream.close();
        outputStream.close();
    }

注意:flush() 刷新缓冲的输出流。这将强制将任何缓冲的输出字节写出到基础输出流,也就是说可以不用关闭流,强制性的写到磁盘上,建议在文件关闭前刷新一下

Tips:流的关闭也是有顺序的
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常

示例:

public static void readAndWriteFileByBufferedOutputStream(File file) {
        FileInputStream fileInputStream = null;
        BufferedOutputStream outputStream=null;
        FileOutputStream fileOutputStream = null;
        BufferedInputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(fileInputStream);
            outputStream = new BufferedOutputStream(new FileOutputStream("E:\\a.txt"));
            fileInputStream = new FileInputStream(file);
            fileOutputStream = new FileOutputStream("E:\\a.txt");
            byte[] buffer = new byte[1024];
            int read = 0;
            while ((read = inputStream.read(buffer))!=-1){
                System.out.println(read);
                outputStream.write(buffer,0,read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileInputStream!= null){
                try {
                    fileInputStream.close();
                    if (fileOutputStream!=null){
                        fileOutputStream.close();
                    }
                    outputStream.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
	at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
	at java.io.FilterInputStream.read(FilterInputStream.java:107)
	at com.etime.homework.test.DateDemo.readAndWriteFileByBufferedOutputStream(DateDemo.java:229)
	at com.etime.homework.test.DateDemo.main(DateDemo.java:20)

FileReader 和 FileWriter

方式一: 一个一个字符的读取

public static void ReaderAndWriterFileByChar(String path) throws IOException {
        FileReader fileReader = new FileReader(path);
        File file;
        FileWriter fileWriter =  new FileWriter("写出的路径", true);
        int len = 0;
        while ((fileReader.read())!=-1){
            fileWriter.write(len);
        }
        fileWriter.flush();
        fileReader.close();
        fileWriter.close();
    }

方式二: 通过字符数组读取

public static void ReaderAndWriterFileByChars(String path) throws IOException{
        FileReader fileReader = new FileReader(path);
        File file;
        FileWriter fileWriter =  new FileWriter("", true);
        int len = 0;
        char[] chars = new char[1024];
        while ((len = fileReader.read(chars))!=-1){
            fileWriter.write(chars,0,len);
        }
        fileWriter.flush();
        fileReader.close();
        fileWriter.close();
    }

BufferedReader 和 BufferedWriter

方式一: 一个一个字符的读取

public static void bufferReaderAndWriterFileByChar (String path) throws IOException{
        BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("写出的路径"));
        int len =0;
        while ((len = bufferedReader.read())!=-1){
            bufferedWriter.write(len);
        }
        bufferedWriter.flush();
        bufferedReader.close();
        bufferedWriter.close();
    }

方式二: 通过字符数组读取

    public static void bufferReaderAndWriterFileByChars (String path) throws IOException{
        BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(" 写出的路径"));
        int len =0;
        char[] chars = new char[1024];
        while ((len = bufferedReader.read(chars))!=-1){
            bufferedWriter.write(chars,0,len);
        }
        bufferedWriter.flush();
        bufferedReader.close();
        bufferedWriter.close();
    }

方式三:一行一行的读取

   public static void bufferReaderAndWriterFileByLine (String path) throws IOException{
       BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
       BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("写出的路径"));
       String line ="";
       while ((line = bufferedReader.readLine())==null){
           bufferedWriter.write(line);
           bufferedWriter.newLine();//注意换行,不建议使用 \n 或者  \r\n
       }
       bufferedWriter.flush();
       bufferedReader.close();
       bufferedWriter.close();
   }

一般情况下,我们在使用时, 如果目的对象是文本,建议使用带缓冲的的字符流,效率较高。
在读取图片,音频之类的,使用字节流较好

你可能感兴趣的:(IO,java,IO流,读写文件,OutputStream)