字符流的概述以及使用

本文介绍了Java中的字符流,包括FileWriter和FileReader的基本使用,如何利用字符流复制文件,flush与close方法的区别,以及字符流写入数据的四种方法。文章还提到了续写、换行的实现,并讨论了在不同操作系统下的换行符。最后,文章讨论了异常处理,特别是JDK7引入的try-with-resources语句以简化资源释放。

字符流 概述以及基本使用

字符流 :数据流格式的一种,能有效避免字符流引起的中文乱码的问题
通常使用的类 FileWriter(字符输出流) FileReader(字符输入流)
这2个类都有各自的构造方法,大致相同
比如FileWriter 常用的构造方法

  • FileWriter (String filename, boolean append)
    filename: 是指定好目标文件地址
    append :是指 是否要在原有数据的基础上追加,true:追加。false:覆盖

  • FileWriter (File file,boolean append)
    file: 是指定好文件对象

利用字符流复制文件
1、创建两个对象,一个是输入,一个输出,在构造方法中绑定写入数据的目的地
2、利用输入的read方法读取,输出的write方法(字符转换为字节的过程)写入
3、若不关闭流文件,要flush方法才能把内存缓存区的内容刷新到文件中
3、释放资源(会先刷新,再关闭文件)

代码:

//1、创建两个对象,一个是输入,一个输出
FileReader fread = new FileReader("C:\\abc.txt");
FileWriter fwri = new FileWriter("C:\\aaa.txt");

int len;//读取的有效个数
char[] cc = new char[1024];//读取的缓存数组

//2、利用输入的read方法读取,输出的write方法写入
while((len = fread.read(cc)!=-1)){
	fwri.writer(cc,0,len);
}

//3、释放资源
fwri.close();
fread.close();

flush 和 close方法的区别

flush方法 :把Buff刷新到写入数据的文件中,流文件还能继续使用。
close方法:先刷新Bufff写入,再通知系统释放资源,关闭流文件。

FileWriter fw = new FileWriter("C:\\aaa.txt");
fw.writer(97);  //写入一个字节 97的编码
fw.flush();		//从buff中刷新到文件中,此时能在文件中查看到 97编码的数值
fw.writer(56);	//流对象还存在,再写入一个字节,存放在buff区中
fw.close();		//流对象关闭,第二次写入的56编码 此时能在文件中查看
fw.writer(98);	//报错,提示文件流已关闭

字符流写入数据的四种方法

write​(char[] cbuf)
write​(char[] cbuf, int off, int len)
write​(String str) 可以通过字符串写入
write​(String str, int off, int len) 可以指定字符串的范围

续写 和 换行

续写和换行都跟字节流的差不多

  • 开启续写: 通过 FileWriter​(File file, boolean append) 构造方法里的append赋值:true即可

  • 换行 根据系统系统的不同
    windows :\r\n
    mac:\r
    linux:\n

使用try catch 语句处理异常

try{
// 可能会触发异常的语句
}catch(//声明扑捉异常的类型){
// 扑捉异常进行处理
}finally{
//一定会执行的语句
比如释放资源
}

//在此处声明 字符流对象 并且要初始化为 null
try{
	// 可能会触发异常的语句
	FileReader fread = new FileReader("C:\\abc.txt");  //如果在此处声明变量,那finally的变量将会报错 ,所有必须提升变量的作用域
	FileWriter fwri = new FileWriter("C:\\aaa.txt");
	int len;//读取的有效个数
	char[] cc = new char[1024];//读取的缓存数组
	//2、利用输入的read方法读取,输出的write方法写入
	while((len = fread.read(cc)!=-1)){
		fwri.writer(cc,0,len);
	}
}catch(IOException e){
	// 扑捉异常进行处理
	System.out.print(e);
}finally{//一定会执行的语句
	
	//3、释放资源
	fwri.close();  //由于变量声明为 null ,触发了nullpointerException 异常,再同try 语句处理
	fread.close();  //并且要进行判断 流对象是否为空。
}

jdk7针对异常的优化

// try语句中增加了小括号的初始化,起到提升变量作用,而且还能自动释放流对象
// 不用手动close,释放资源 节省了 finally语句,使得代码简洁明了
try**()**{
// 可能会触发异常的语句
}catch(//声明扑捉异常的类型){
// 扑捉异常进行处理
}finally{
//一定会执行的语句
比如释放资源
}

//jdk 7 优化之后的代码
try(FileReader fread = new FileReader("C:\\abc.txt");  //如果在此处声明变量,那finally的变量将会报错 ,所有必须提升变量的作用域
	FileWriter fwri = new FileWriter("C:\\aaa.txt");
	){
	int len;	//读取的有效个数
	char[] cc = new char[1024]; //读取的缓存数组
	//2、利用输入的read方法读取,输出的write方法写入
	while((len = fread.read(cc)!=-1)){
		fwri.writer(cc,0,len);
	}
}catch(IOException e){
	// 扑捉异常进行处理
	System.out.print(e);
}
<think> 我们参考提供的引用资料来回答关于Java字符流的问题。 根据引用[1]和[2]:Java IO流按照操作数据的不同分为字节流和字符流字符流专门用于处理字符数据,它们能够自动处理字符编码问题,简化了字符数据的读写。 字符流的两个核心抽象类:Reader和Writer。 引用[2]指出:在IO包中,字符流的输入输出流分别用java.io.Reader和java.io.Writer表示。 引用[5]提供了关于字符流更详细的内容,包括转换流(如OutputStreamWriter)和编码解码问题。 因此,我们可以将回答分为以下几个部分: 1. 字符流概述 2. 字符流的核心类:Reader和Writer 3. 字符流使用方法(包括转换流) 4. 编码与解码 5. 缓冲流(BufferedReader/BufferedWriter)提高效率 注意:根据引用[3]和[4],缓冲流是一种包装流,用于提高IO效率。对于字符流,同样有缓冲流。 另外,引用[4]提到了使用try-with-resources自动关闭资源。 下面开始组织回答: </think> ### Java字符流介绍 Java字符流Java I/O体系中专门处理**字符数据**的API,基于Unicode编码设计,适用于文本数据处理。与字节流直接操作字节不同,字符流通过自动处理字符编码和解码,简化了文本读写操作。 #### 一、字符流核心类 1. **输入流** - `Reader`:抽象基类 - 常用子类: - `InputStreamReader`:字节到字符的桥梁(转换流) - `FileReader`:文件字符输入流(`InputStreamReader`子类) - `BufferedReader`:带缓冲的字符输入流 2. **输出流** - `Writer`:抽象基类 - 常用子类: - `OutputStreamWriter`:字符到字节的桥梁(转换流) - `FileWriter`:文件字符输出流(`OutputStreamWriter`子类) - `BufferedWriter`:带缓冲的字符输出流 #### 二、字符流核心方法 ```java // 读取方法(Reader) int read():读取单个字符 → 返回字符的ASCII值(-1表示结束) int read(char[] cbuf):读取字符数组 → 返回实际读取长度 // 写入方法(Writer) void write(int c):写入单个字符 void write(char[] cbuf):写入字符数组 void write(String str):写入字符串 ``` #### 三、关键特性 1. **编码与解码** - 编码(字符→字节):`String.getBytes(charsetName)` - 解码(字节→字符):`new String(bytes, charsetName)` - 示例(引用[5]): ```java byte[] bytes = {97, 98, 99}; String str = new String(bytes, "UTF-8"); // 解码为"abc" ``` 2. **转换流** - `InputStreamReader`/`OutputStreamWriter`解决字节流→字符流转换: ```java // 构造方法(引用[5]) OutputStreamWriter(OutputStream out) // 默认编码 OutputStreamWriter(OutputStream out, String charsetName) // 指定编码 ``` 3. **缓冲流优化** - 包装基础流提升性能(引用[3][4]): ```java // 缓冲读取示例 try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { String line; while ((line = br.readLine()) != null) System.out.println(line); } // try-with-resources自动关闭 ``` #### 四、字符流使用场景 1. 文本文件读写(`.txt`, `.csv`等) 2. 需处理字符编码的场景(如UTF-8/GBK转换) 3. 需按行读取内容的场景(`BufferedReader.readLine()`) 4. 需高频读写文本时(缓冲流减少I/O操作) > ⚠️ **注意事项** > - 字符流**不能**处理非文本数据(如图片、音频) > - 必须显式关闭流或使用`try-with-resources`(引用[4]) > - 指定编码避免乱码(推荐UTF-8) ### 典型示例 写入文件(引用[4]优化版): ```java try (OutputStreamWriter writer = new OutputStreamWriter( new FileOutputStream("data.txt"), StandardCharsets.UTF_8)) { writer.write("Hello, 字符流!"); // 自动编码为UTF-8字节 } // 自动关闭流并刷新缓冲区 ``` --- ### 相关问题 1. 字符流和字节流的本质区别是什么?各自适用哪些场景? 2. 为什么处理中文文本时推荐使用字符流而非字节流? 3. 如何通过`BufferedReader`实现高效的大文本文件读取? 4. 字符流处理过程中出现乱码的可能原因有哪些?如何解决? [^1][^2][^4][^5]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值