Reader
(输入字符流)和Writer
(输出字符流)。InputStream
提供了read()
方法来逐个字节地读取数据。这个方法返回一个int
值,范围是 0 - 255,表示读取到的字节数据(该方法一次读取一个字符并以整数格式返回其ASCII值),需要转为char类型,当返回 - 1 时,表示已经到达流的末尾。
如果读取的文件中含有汉字,会产生乱码。utf8汉字有3个字节,但是read()方法一次只能读取一个字节,无法正常读取
在这里会产生异常,可以使用throws IOException 或者try catch finally抛出,最好使用后者
因为最后需要关闭文件流释放资源,
fileInputStream是inputStream的子类,也拥有read()方法,在这里使用fileInputStream来读取文件
@Test public void readFile01() { String filePath = "D:\\hello.txt"; int readData = 0; FileInputStream fileInputStream = null; try { // 创建FileInputStream对象 用于读取文件 fileInputStream = new FileInputStream(filePath); // 从输入流读取一个字节的数据,如果没有输入可用,返回-1,结束 // 需要抛出异常 IOException while ((readData = fileInputStream.read()) != -1) { // utf-8 汉字是3个字节,输入汉字会乱码 System.out.println((char)readData); } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭文件流,释放资源 try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
// 使用 read(byte[] b) 读取文件,提高效率 // 读取次数减少,但是汉字还是会乱码 @Test public void readFile02() { String filePath = "d:\\hello.txt"; // int readData = 0; // 字节数组 byte[] buf = new byte[8]; // 一次读取八个字节,读取字节数可以改变 int readLen = 0; FileInputStream fileInputStream = null; try { // 创建FileInputStream对象 用于读取文件 fileInputStream = new FileInputStream(filePath); // 需要抛出异常 IOException // 关闭文件流,释放资源 // try { // fileInputStream.close(); // } catch (IOException e) { // e.printStackTrace(); // } while ((readLen = fileInputStream.read(buf)) != -1) { // 从输入流中每次读取8或数据到buf中,8个数据是因为byte[8] // readLen是 返回每次读取数据的个数,只能<=8 System.out.println(new String(buf, 0, readLen)); // length的长度不能大于数组的 // 从每次读取到的数据中取出length长度的数据 } } catch (IOException e) { e.printStackTrace(); } finally { } }
OutputStream提供了write(int b)方法用于逐个字节地输出数据。这个方法接收一个int类型的参数,但是实际上只使用了这个int值的最低一个字节(因为字节是 8 位,int是 32 位)来写入目标。
更高效的方式是使用write(byte[] b)
方法,它可以将一个字节数组中的数据一次性输出到目标。还有一个重载的方法write(byte[] b, int off, int len)
,可以指定字节数组中的起始位置off
和要输出的长度len
@Test public void writeFile(){ String filePath = "d:\\a.txt"; FileOutputStream fileOutputStream = null; try { // 1. new FileOutputStream(filePath); 写入内容覆盖原来 // 2. new FileOutputStream(filePath, true); 写入内容包含原来 fileOutputStream = new FileOutputStream(filePath,true); // 写入一个字节 // fileOutputStream.write('H'); // 写入字符串 String str = "aaaaadddd"; // str.getBytes() 可以把字符串转为字节数组 // fileOutputStream.write(str.getBytes()); // 写入指定范围的字符 fileOutputStream.write(str.getBytes(),0,4); } catch (IOException e) { e.printStackTrace(); } finally { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
FileReader
是 Java 中用于读取字符文件的类,它属于字符流范畴字符编码转换:在底层,计算机存储文件是以字节为单位的。而FileReader会根据指定的字符编码将字节转换为字符。如果没有指定编码,它会使用系统默认的字符编码(例如在大多数中文系统中可能是 GBK 或者 UTF - 8)。这个转换过程是在读取数据时自动完成的。
与底层字节流的关系:实际上,FileReader
在内部会创建一个FileInputStream
(字节流)来读取文件中的字节,然后通过InputStreamReader
将字节流转换为字符流。所以,FileReader
是在字节流的基础上构建的,是对字节流读取和字符转换操作的一种封装,使得开发者可以更方便地专注于字符级别的文本处理
读取方法:逐个字符读取:FileReader提供了read()方法来逐个字符地读取文件内容。这个方法返回一个int值,范围是 0 - 65535(该方法一次读取一个字符并以整数格式返回其ASCII值),表示读取到的字符的 Unicode 编码值,当返回 - 1 时,表示已经到达文件末尾。
FileReader fileReader = new FileReader("example.txt");
int data;
while ((data = fileReader.read())!= -1) {
// 处理读取到的字符,例如打印出来
System.out.print((char) data);
}
fileReader.close();
读取到字符数组:除了逐个字符读取,还可以使用read(char[] cbuf)方法将文件内容读取到一个字符数组中。这个方法会尝试读取最多cbuf.length个字符到字符数组cbuf中,并返回实际读取的字符数。如果返回 - 1,则表示已经到达文件末尾。
FileReader fileReader = new FileReader("example.txt");
char[] buffer = new char[1024];
int charsRead;
while ((charsRead = fileReader.read(buffer))!= -1) {
// 处理读取到的字符数组,例如打印出来
System.out.print(new String(buffer, 0, charsRead)); }
fileReader.close();
Writer是抽象类,它有许多子类,如FileWriter、BufferedWriter、CharArrayWriter、StringWriter、PipedWriter等。这些子类实现了不同的功能,以适应各种具体的写入场景。
(1)FIleWriter
try {
FileWriter writer = new FileWriter("example.txt");
String text = "Hello, World!";
writer.write(text);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
首先创建了一个FileWriter对象,指定要写入的文件名为example.txt。然后使用write方法将字符串"Hello, World!"写入文件。最后,通过close方法关闭FileWriter,释放相关资源。
(2) 字符数组和字符串写入(CharArrayWriter 和 StringWriter)
CharArrayWriter用于将字符写入字符数组,它可以将写入的字符数据存储在一个内部的字符数组中。例如,可以用于在内存中构建字符数据,然后获取这个字符数组进行后续操作。
StringWriter类似,不过它是用于构建字符串。它会将写入的字符数据转换为一个字符串,可以通过toString方法获取构建的字符串。