Java IO流原理及流的体系——节点流(文件流)
文章目录
- 前言
- 一、Java IO原理
- 二、流的体系
-
- 1.流的分类
- 2.流的体系
- 三、节点流和处理流
-
- 1.节点流
- 2.处理流
- 四、代码实现
-
- 1.FileReader 和 FileWriter 的使用
- 2.FileInputStream 和 FileOutputStream 的使用
- 总结
前言
I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。java.io包下提供了各种“流”类和接口,用来获取不同种类的数据,并通过标准的方法输入或输出数据。
一、Java IO原理
1、输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
2、输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
二、流的体系
1.流的分类
● 按操作数据单位不同分为: 字节流(8 bit),字符流(16 bit)
● 按数据流的流向不同分为: 输入流,输出流
● 按流的角色的不同分为: 节点流,处理流
2.流的体系
Java的IO流共涉及40多个类,实际上非常规则,都是从4个抽象基类派生的。由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
三、节点流和处理流
1.节点流
● 节点流:直接从数据源或目的地读写数据。
2.处理流
● 处理流:不直接连接到数据源或目的地,而是“连接” 在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写
四、代码实现
1.FileReader 和 FileWriter 的使用
package zzz.xxx.java;import org.junit.Test;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class FileReaderWriterTest { /* 说明: 1、read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1。 2、异常的处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally处理。 3、读入的文件一定要存在,否则会报FileNotFoundException。 */ @Test public void testFileReader(){ FileReader fileReader = null; try { // 1、实例化File类的对象,指明要操作的文件 File file = new File("hello.txt"); // 相较于当前的module // 2、提供具体的流 fileReader = new FileReader(file); // 3、数据的读入 // read():返回读入的一个字符。如果达到文件末尾,返回-1 // 方式一:// int data = fileReader.read();// while (data != -1) {// System.out.print((char) data);// data = fileReader.read();// } // 方式二:语法上针对方式一的修改 int data; while ((data = fileReader.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、流的关闭操作// try {// if (fileReader != null) {// fileReader.close();// }// } catch (IOException e) {// e.printStackTrace();// } // 或 if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } // 对read()操作升级,使用read的重载方法 @Test public void testFileReader1(){ FileReader fr = null; try { // 1、File类的实例化 File file = new File("hello.txt"); // 2、FileRead流的实例化 fr = new FileReader(file); // 3、读入的操作 // read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1。 char[] cbuf = new char[5]; int len = fr.read(cbuf); while (len != -1) { // 方式一:// // 错误的写法 for (int i = 0; i < cubf.length; i++) { System.out.print(cbuf[i]); }// // 正确的写法// for (int i = 0; i < len; i++) {// System.out.print(cbuf[i]);// }// len = fr.read(cbuf); // 方式二: // 错误的写法// String str = new String(cbuf);// System.out.println(str); // 正确的写法 String str = new String(cbuf, 0, len); System.out.print(str); len = fr.read(cbuf); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、资源的关闭 if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 从内存中写出数据到硬盘的文件中 说明: 1、输出操作,对应的File可以不存在。并不会报异常。 2、File对应的硬盘中的文件:如果不存在,在输出的过程中,会自动创建此文件。 File对应的硬盘中的文件:如果存在: 如果流使用的构造器是FileWriter(file, false) / FileWriter(file):对原有文件的覆盖 如果流使用的构造器是FileWriter(file, true):不会覆盖原有文件,而是在原有文件基础上追加内容 */ @Test public void testFileWriter() { FileWriter fw = null; try { // 1、提供File类的对象,指明写出到的文件 File file = new File("hello1.txt"); // 2、提供FileWriter的对象,用于数据的写出 fw = new FileWriter(file, false); // 3、数据的写出操作 fw.write("helloworld\n"); fw.write("I have a dream!"); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null) { // 4、关闭资源 try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testFileReaderFileWriter(){ FileReader fr = null; FileWriter fw = null; try { // 1、创建File类的对象,指明读入和写出的文件 File srcFile = new File("hello.txt"); File destFile = new File("hello2.txt"); // 字符流不能用来处理图片等字节型文件// File srcFile = new File("雷神壁纸.png");// File destFile = new File("雷神壁纸1.png"); // 2、创建输入流和输出流的对象 fr = new FileReader(srcFile); fw = new FileWriter(destFile); // 3、数据的读入和写出操作 char[] cbuf = new char[5]; int len; // 记录每次读入到cbuf数组中的字符的个数 while ((len = fr.read(cbuf)) != -1) { // 每次写出len个字符 fw.write(cbuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、流资源的关闭 // 方式一:// try {// if (fw != null) {// fw.close();// }// } catch (IOException e) {// e.printStackTrace();// }// try {// if (fr != null) {// fr.close();// }// } catch (IOException e) {// e.printStackTrace();// } // 方式二: try { if (fw != null) { fw.close(); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fr != null) { fr.close(); } } catch (IOException e) { e.printStackTrace(); } } } }}
2.FileInputStream 和 FileOutputStream 的使用
package zzz.xxx.java;import org.junit.Test;import java.io.*;/* 结论: 对于文本文件(.txt, .java, .c, .cpp),使用字符流处理 对于非文本文件(.jpg, .mp4, .avi, .png, .doc, .ppt, ....),使用字节流处理 */public class FileInputOutputStream { /* 使用字节流FileInputStream处理文本文件,可能出现乱码。 */ @Test public void testFileInputStream() { FileInputStream fis = null; try { // 1、创建File类的对象,指明读入的文件 File file = new File("hello.txt"); // 2、创建FileInputStream类的对象,用于数据的读入 fis = new FileInputStream(file); // 3、数据的读入操作 byte[] buffer = new byte[5]; int len; while ((len = fis.read(buffer)) != -1) { String str = new String(buffer, 0, len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、流资源的关闭 if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 实现对图片的复制操作 */ @Test public void testFileInputOutputStream() { FileInputStream fis = null; FileOutputStream fos = null; try { // 1、创建File类的对象,指明读入和写出的文件 File srcFile = new File("雷神壁纸.png"); File destFile = new File("雷神壁纸2.png"); // 2、创建输入流和输出流的对象 fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); // 3、数据的读入和写出操作 byte[] buffer = new byte[5]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、流资源的关闭 if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 实现复制文件的方法。适用于字节型文件。 就文件的复制而言,字符型文件也可以适用。 */ public void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutputStream fos = null; try { // 1、创建File类的对象,指明读入和写出的文件 File srcFile = new File(srcPath); File destFile = new File(destPath); // 2、创建输入流和输出流的对象 fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); // 3、数据的读入和写出操作 byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { fos.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { // 4、流资源的关闭 if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testCopyFile() { long start = System.currentTimeMillis(); String srcPath = "C:\\Users\\A\\Desktop\\IO流概述.avi"; String destPath = "C:\\Users\\A\\Desktop\\IO流.avi"; // 就文件的复制而言,字符型文件也可以适用,不会出现乱码// String srcPath = "hello.txt";// String destPath = "hello3.txt"; copyFile(srcPath, destPath); long end = System.currentTimeMillis(); System.out.println("复制操作花费的时间为:" + (end - start) + "毫秒"); }}
总结
以上就是今天分享的内容,本文仅仅简单介绍了IO流的使用,需要详细教程的伙伴可私信联系。
来都来了,点赞 收藏 加关注再走吧 ~ ~ ~