JAVA_基础IO流原理及流的分类(二)

IO流的分类

I/Oinput/output的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输。如:读写文件、网络通信等。在Java程序中,对于数据的输入/输出操作以:流(stream)的方式进行。

流的分类

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)

  • 按数据流的流向不同分为:输入流,输出流

  • 按流的角色的不同分为:节点流,处理流

    (抽象基类) 字节流 字符流
    输入流 inputStream Reader
    输出流 OutputStream Writer

IO流体系结构

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream
FilterInputStream FilterOutputStream
打印流 PrintStream printWiter
推回输入流 PushbackInputStream PushbackReader
特殊流 DataInputStream DataOutputStream

流的使用

对于处理文本文件(.txt,.java,.c,.cpp),使用字符流处理。

对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,....),使用字节流处理

字符输入流

read(): 返回读入的一个字符。如果达到文件末尾,返回-1。
异常处理:为了保证流资源一旦执行后,能够执行关闭操作,需要使用try-catch-findlly处理。
读入的文件一定要存在,否则就会报FileNotfoundException

public void testFileReader() {
    FileReader fr = null;
    try {
        // 1.实例化File类的对象,指明要操作的文件
        File file = new File("hello.txt");// 相较于当前Module
        // 2.提供具体的流
        fr = new FileReader(file);
        // 3.数据的读入过程
        int data = fr.read();
        while(data != -1) {
            System.out.print((char)data);
            data = fr.read();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.流的关闭操作
        try {
            if(fr != null) fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符输出流

输出操作,对应的File可以不存在的。

File对应的硬盘中的文件不存在,则在输出的过程中自动创建文件。
File对应的硬盘中的文件存在:

  • 流使用的构造器是FileWriter(file,false)FileWriter(file):对源文件做覆盖。
  • 流使用的构造器是FileWriter(file,true):对源文件内做追加。
public void testFileWriter() {
    FileWriter fileWriter = null;
    try {
        // 1.提供File类的对象,指明写出到的文件
        File file = new File("hello1.txt");
        // 2.提供FileWriter的对象,用于数据的写出
        // FileWriter fileWriter = new FileWriter(file);
        // FileWriter fileWriter = new FileWriter(file,true);
        FileWriter fileWriter = new FileWriter(file,false);
        // 3.写出的操作
        fileWriter.write("I have a dream!\n");
        fileWriter.write("you need to have a dream!\n");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.流资源的关闭操作
        if (fileWriter != null) {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

字符输入流与字符输出流案例

public void testFileReaderFileWriter() {
    FileReader fileReader = null;
    FileWriter fileWriter = null;
    try {
        // 1.创建File类对象,指明读入和写出的文件
        File srcFile1 = new File("hello.txt");
        File srcFile2 = new File("hello2.txt");
        // 2.创建输入流与输出流对象
        fileReader = new FileReader(srcFile1);
        fileWriter = new FileWriter(srcFile2);
        // 3.数据的读入与写出操作
        char[] cbuf = new char[5];
        int len;// 记录每次读入到数组中字符的个数
        while((len = fileReader.read(cbuf)) != -1) {
            // 从0开始,每次写出len个字符
            fileWriter.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.关闭流资源
        try {
            if (fileWriter != null) fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fileReader != null) fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节输入流与字符输出流

FileInputStreamFileOutputStream:使用方法与字符流一致,在处理文本文件是有可能出现乱码。

  1. 创建File类对象,指明读入和写出的文件。
  2. 创建输入流与输出流对象。
  3. 数据的读入与写出操作。
  4. 关闭流资源。
public void testFileInputOutputStream() {
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            File srcFile = new File("image.png");
            File destFile = new File("image2.png");
            inputStream = new FileInputStream(srcFile);
            outputStream = new FileOutputStream(destFile);
            // 复制的过程
            byte[] buffer = new byte[5];
            int len;
            while((len = inputStream.read(buffer)) != -1) {
                // 从0开始,每次写出len个字符
                outputStream.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (inputStream != null) inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

处理流:缓冲流

作用:提供流的读取、写入的速度。

缓冲流资源关闭:先关闭外层流(缓冲流),在关闭内层的流(节点流)。

在关闭外层流(缓冲流)的同时,内层流(节点流)也会自动的进行关闭。所有内层的关闭流可以省略。

// 非文本文件的复制
public void BufferedStreamTest() {
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        // 1.造文件
        File srcFile = new File("image.png");
        File destFile = new File("image3.png");
        // 2.造流
        // 2.1 造节点流
        FileInputStream fileInputStream = new FileInputStream(srcFile);
        FileOutputStream fileOutputStream = new FileOutputStream(destFile);
        // 2.2 造缓冲流
        bufferedInputStream = new BufferedInputStream(fileInputStream);
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        // 3.复制的细节:读取、写入
        byte[] bytes = new byte[10];
        int len;
        while ((len = bufferedInputStream.read(bytes)) != -1) {
            bufferedOutputStream.write(bytes,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.资源关闭
        // 要求:先关闭外层流,在关闭内层的流
        try {
            if (bufferedOutputStream != null) bufferedOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bufferedInputStream != null) bufferedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 在关闭外层流的同时,内层流也会自动的进行关闭。所有内层的关闭流可以省略
 //        fileOutputStream.close();
 //        fileInputStream.close();
    }
}

flush():只要是缓冲输出流都会有flush()刷新操作。

// 实现文件复制的方法
public void copyFileWithBuffered(String srcPath,String destPath) {
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        // 1.造文件
        File srcFile = new File(srcPath);
        File destFile = new File(destPath);
        // 2.造流
        // 2.1 造节点流
        FileInputStream fileInputStream = new FileInputStream(srcFile);
        FileOutputStream fileOutputStream = new FileOutputStream(destFile);
        // 2.2 造缓冲流
        bufferedInputStream = new BufferedInputStream(fileInputStream);
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        // 3.复制的细节:读取、写入
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(bytes)) != -1) {
            bufferedOutputStream.write(bytes,0,len);
            //                bufferedOutputStream.flush();// 刷新缓冲区
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 4.资源关闭
        // 要求:先关闭外层流,在关闭内层的流
        try {
            if (bufferedOutputStream != null) bufferedOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bufferedInputStream != null) bufferedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public void testCopyFile() {
    long start = System.currentTimeMillis();
    String srcPath = "F:\\视频.avi";
    String destPath = "F:\\视频2.avi";
    copyFileWithBuffered(srcPath,destPath);
    long end = System.currentTimeMillis();
    System.out.println( "复制文件消耗时间:" + (end - start));
}

readLine():一次输出一行,不报行换行符。
newLine():提供换行操作。

public void testBufferedReaderBufferedWriter() {
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        bufferedReader = new BufferedReader(new FileReader(new File("hello.txt")));
        bufferedWriter = new BufferedWriter(new FileWriter(new File("hello3.txt")));
        String data;
        while((data = bufferedReader.readLine()) != null) {
            bufferedWriter.write(data);// data中不包含换行符
            bufferedWriter.newLine();// 提供换行操作
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        try {
            if (bufferedWriter != null) bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bufferedReader != null) bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理流:转换流

转换流提供了在字节流和字符流之间的转换:
InputStreamReader(属于字符流):将一个字节的输入流,转换为字符的输入流。
OutputStreamWriter(属于字符流):将一个字符的输出流,转换为字节的输出流。

public void test2() {
    InputStreamReader inputStreamReader = null;
    OutputStreamWriter outputStreamWriter = null;
    try {
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_gbk.txt");

        FileInputStream fileInputStream = new FileInputStream(file1);
        FileOutputStream fileOutputStream = new FileOutputStream(file2);

        inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
        outputStreamWriter = new OutputStreamWriter(fileOutputStream,"GBK");

        char[] cbuf = new char[1024];
        int len;
        while((len = inputStreamReader.read(cbuf)) != -1) {
            outputStreamWriter.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (outputStreamWriter != null) outputStreamWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (inputStreamReader != null) inputStreamReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
posted @ 2021-01-04 09:53  TuoYingtao  阅读(99)  评论(0编辑  收藏  举报