概述
生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了 ctrl+s ,可能文件就白白编辑
了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出output ,即流向内存是输入流,流出内存的输出流。
顶级父类
字节流
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
字节输入流
字节输出流
字符流
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。
字符输入流
字符输出流
字节输入流-FileInputStream
/**
* 挨个读取字节并转化为字符输出
* @param
*/
public static void readToOneByOne() {
File file = new File("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\testForEnglish.txt");
int flag = 0;
try {
FileInputStream fileInputStream = new FileInputStream(file);
while ((flag = fileInputStream.read()) != -1) {
System.out.print((char) flag);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 挨个读取字节并转化为字符输出
* @param
*/
public static void readToArray() {
File file = new File("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\testForEnglish.txt");
int flag = 0;
byte[] arr = new byte[2];
try {
FileInputStream fileInputStream = new FileInputStream(file);
while ((flag = fileInputStream.read(arr)) != -1) {
// System.out.print(new String(arr)); // 每次都打印两个字节,会有异常。
System.out.print(new String(arr,0,flag)); //优化后打印读取的字节数。
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//
}
字节输出流-FileOutputStream
/**
* 写出内存
*/
public static void writeToOneByOneOrByArr() {
try {
int len = 0;
byte[] bytes = new byte[2];
FileInputStream fileInputStream = new FileInputStream("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\testForEnglish.txt");
FileOutputStream fileOutputStream = new FileOutputStream(new File("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\ouTest.txt"));
while ((len = fileInputStream.read(bytes)) != -1) {
// 写入
// fileOutputStream.write(bytes);
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
字符输入流-FileReader
/**
* 字符流读入数据到内存
*/
private static void readByChars() {
int len = 0;
char[] arr = new char[2];
try {
FileReader fileReader = new FileReader("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\testForChinese.txt");
// while ((len = fileReader.read()) != -1) {
// // 逐字读取
// System.out.print((char) len);
// }
while ((len = fileReader.read(arr)) != -1) {
// 字符数组读取
// System.out.print(new String(arr));
System.out.print(new String(arr,0,len));
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
字符输入流-FileWriter
/**
* 字符输出流
*/
private static void writeByChars() {
char[] arr = {'y','y'};
// 指定输出位置
// try {
// FileWriter fileWriter = new FileWriter("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\writeByChars.txt");
// fileWriter.write("永远年轻,永远热泪盈眶");
// fileWriter.flush();
// fileWriter.close();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// 使用try-catch-resource 可以自动刷新文件关闭资源
// try (FileWriter fileWriter = new FileWriter("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\writeByChars.txt")) {
// fileWriter.write("永远年轻,永远热泪盈眶!!!!!!!!!");
// fileWriter.write("\t\n");
// fileWriter.write(98);
// fileWriter.write('t');
// fileWriter.write(arr);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
try (FileWriter fileWriter = new FileWriter("F:\\Java\\JavaSE\\Base\\base\\src\\main\\resources\\writeByChars.txt",true)) {
fileWriter.write("\t\nTI 大魔王");
} catch (IOException e) {
throw new RuntimeException(e);
}
//
}
在上面的实例代码中,对文件进行写操作的时候,我们一定要在最后使用刷新和关闭操作