最近很多小伙伴都在问Java学习日志和19-1-IO流-BufferedReader这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展BufferedReader和BufferedW
最近很多小伙伴都在问Java学习日志和19-1-IO流-BufferedReader这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展BufferedReader 和BufferedWriter、BufferedReader和BufferedInputStream之间的区别、BufferedReader和BufferedWriter、BufferedReader和BufferedWriter简介等相关知识,下面开始了哦!
本文目录一览:- Java学习日志(19-1-IO流-BufferedReader)(java io 流)
- BufferedReader 和BufferedWriter
- BufferedReader和BufferedInputStream之间的区别
- BufferedReader和BufferedWriter
- BufferedReader和BufferedWriter简介
Java学习日志(19-1-IO流-BufferedReader)(java io 流)
字符流的缓冲区
缓冲区的出现提高了对数据的读写效率
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才能使用
在流的基础上对流的功能进行了增强
BufferedWriter
/*
缓冲区的出现是为了提高流的操作效率而出现的
创建缓冲区之前必须要有流对象
*/
import java.io.*;
class BufferedWriterDemo{
public static void main(String[] args)throws Exception{
// 创建一个流对象
FileWriter fw=new FileWriter("buf.txt");
// 提高写入效率,加入缓冲技术
// 将需要提高效率的流对象作为参数传递给缓冲区的构造函数
BufferedWriter bufw=new BufferedWriter(fw);
bufw.write("IloveXB");
bufw.flush();
// 关闭缓冲区就是关闭流对象,不再fw.close();
bufw.close();
}
}
缓冲区特有方法
newLine();换行,Windows与Linux通用
BufferedReader
/*
字符读取流缓冲区
*/
import java.io.*;
class BufferedReaderDemo{
public static void main(String[] args)throws Exception{
// 创建一个读取流对象和文件相关联
FileReader fr=new FileReader("buf.txt");
// 创建缓冲区
BufferedReader bufr=new BufferedReader(fr);
// 缓冲区特有方法-读取文本行-readLine();
String line=null;
while((line=bufr.readLine())!=null){
System.out.println("line:"+line);
}
bufr.close();
}
}
readLine()只返回回车符之前的数据内容,并不返回回车符
循环中需要加入newLine();
通过缓冲区复制一个.java文件
/*
通过缓冲区复制一个.java文件
*/
import java.io.*;
class CopyTestByBuf{
public static void main(String[] args){
BufferedReader bufr=null;
BufferedWriter bufw=null;
try{
bufr=new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw=new BufferedWriter(new FileWriter("buffWriter_Copy.txt"));
String line=null;
while((line=bufr.readLine())!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch(IOException e){
throw new RuntimeException("读写失败");
}
finally{
try{
if(bufr!=null){
bufr.close();
}
}
catch(IOException e){
throw new RuntimeException("读取关闭失败");
}
try{
if(bufw!=null){
bufw.close();
}
}
catch(IOException e){
throw new RuntimeException("写入关闭失败");
}
}
}
}
readLine()原理
不论是读一行或读取多个字符,最终使用的都是read(),一次读一个
MyBufferedReader-自定义
利用readLine原理自定义功能,模拟BufferedReader
import java.io.*;
class MyBufferedReader{
private FileReader r;
MyBufferedReader(FileReader r){
this.r=r;
}
// 可以一次读一行的方法
public String myreadLine()throws IOException{
// 定义一个临时容器,原BufferedReader封装的是字符数组
// 为了方便,定义一个StringBuilder容器,但最终还要变成字符串
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1){
if(ch==''\r''){
continue;
}
if(ch==''\n''){
return sb.toString();
}
else{
sb.append((char)ch);
}
}
if(sb.length()!=0){
return sb.toString();
}
return null;
}
public void myClose()throws IOException{
r.close();
}
}
class MyBufferedReaderDemo{
public static void main(String[] args)throws IOException{
FileReader fr=new FileReader("buf.txt");
MyBufferedReader myBuf=new MyBufferedReader(fr);
String line=null;
while((line=myBuf.myreadLine())!=null){
System.out.println(line);
}
myBuf.myClose();
}
}
BufferedReader 和BufferedWriter
1、BufferedReader
从输入字符流中读取文本,缓冲各个字符,从而实现字符,数组和行的读取。
构造函数 BuffferedReader(reader)
reader 为InputStreamReader.它是安装指定的编码(如GBK)将二进制流转换为字符流。
构造函数
InputStreamReader(InputStream in) Creates an InputStreamReader that uses the default charset. |
InputStreamReader(InputStream in, Charset cs) Creates an InputStreamReader that uses the given charset. |
InputStreamReader(InputStream in, CharsetDecoder dec) Creates an InputStreamReader that uses the given charset decoder. |
InputStreamReader(InputStream in, String charsetName) Creates an InputStreamReader that uses the named charset. |
2、BufferedWriter
输入流:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
构造函数 BufferedWriter(Writer out)
Writer子类
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
BufferedReader和BufferedInputStream之间的区别
之间有什么区别BufferedReader
,BufferedInputStream
并Scanner
在Java?BufferedReader
阅读文本并BufferedInputStream
阅读byte
。除此之外有什么区别吗?
答案1
小编典典我猜想,区别在于阅读器和输入流之间的区别:一种是基于字符的,另一种是基于字节的。例如,阅读器通常支持编码…
编辑:
检查此问题:读取多字节字符时InputStream和InputStreamReader之间的区别
BufferedReader和BufferedWriter
概念
BufferedReader:是一个从字符输入流中读取文本的类。它提供了一个缓冲区,可以一次性读取大量数据,从而减少实际读取操作的次数,提高读取效率。
BufferedWriter:是一个将文本写入字符输出流的类。它提供了一个缓冲区,可以一次性写入大量数据,从而减少实际写入操作的次数,提高写入效率。
主要构造方法
BufferedReader
BufferedReader(Reader in): 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz): 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
BufferedWriter
BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz): 创建一个使用指定大小输出缓冲区的缓冲字符输出流。
public static void main(String[] args) throws IOException {
// BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedReader br1 = new BufferedReader(new FileReader("aaa.txt"));
//BufferedReader(Reader in, int sz): 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
BufferedReader br2 = new BufferedReader(new FileReader("aaa.txt"),8000);
//BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter bw1 = new BufferedWriter(new FileWriter("bbb.txt"));
//BufferedWriter(Writer out, int sz): 创建一个使用指定大小输出缓冲区的缓冲字符输出流。
BufferedWriter bw2 = new BufferedWriter(new FileWriter("bbb.txt"),8000);
}
缓冲区大小
BufferedReader和BufferedWriter的内部缓冲区大小可以通过构造函数来设置。如果不显式设置,默认大小通常是8192字节。
主要方法
BufferedReader
- read(): 读取单个字符并返回。如果已到达流的末尾,则返回-1。
- read(char[] cbuf, int off, int len): 将字符读入数组的一部分。返回读取的字符数,或者在流的末尾返回-1。
- readLine(): 读取一个文本行,返回一个包含行内容的字符串,不包含任何行终止符。如果已到达流的末尾,则返回null。
- ready(): 判断输入流是否准备好进行读取,返回布尔值。
- close(): 关闭流并释放与之关联的所有资源。
public static void main(String[] args) {
//read()
try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
int c;
//read()
//读取单个字符并返回其整数表示,如果已到达流的末尾,则返回-1。
while ((c = br.read())!=-1){
System.out.print((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}
//read(char[] cbuf, int off, int len)
try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
char[] buffer = new char[2];
int numRead;
//read(char[] cbuf, int off, int len)
//将字符读入数组的一部分,返回读取的字符数,或者在流的末尾返回-1。
if ((numRead = br.read(buffer, 0, buffer.length)) != -1) {
System.out.print(new String(buffer, 0, numRead));
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println();
//readLine()
try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
String line;
//readLine()
//读取一个文本行,返回一个包含行内容的字符串,不包含任何行终止符。如果已到达流的末尾,则返回null。
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
//ready()
//判断输入流是否准备好进行读取,返回布尔值。
try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
while (br.ready()) {
System.out.println(br.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedWriter
- write(int c): 写入单个字符。
- write(char[] cbuf, int off, int len): 写入字符数组的一部分。
- write(String s, int off, int len): 写入字符串的一部分。
- newLine(): 写入一个行分隔符。
- flush(): 刷新缓冲区,将缓冲区内容写入输出流。
- close(): 关闭流,并刷新任何缓冲的输出。
public static void main(String[] args) {
//write(int c)
//写入单个字符。
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
bw.write(''H'');
bw.write(''e'');
bw.write(''l'');
bw.write(''l'');
bw.write(''o'');
} catch (IOException e) {
e.printStackTrace();
}
//write(char[] cbuf, int off, int len)
//写入字符数组的一部分。
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
char[] buffer = "Hello, World!".toCharArray();
bw.write(buffer, 0, buffer.length);
} catch (IOException e) {
e.printStackTrace();
}
//write(String s, int off, int len)
//写入字符串的一部分。
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
String str = "Hello, World! write(String s, int off, int len)";
bw.write(str, 0, str.length());
} catch (IOException e) {
e.printStackTrace();
}
//newLine() 写入一个行分隔符。
//flush() 刷新缓冲区,将缓冲区内容写入输出流。
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
bw.write("Hello, World!");
bw.newLine(); // 空一行
bw.write("newLine()");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
try-with-resources
在Java中,try-with-resources语句是用于自动关闭实现了java.lang.AutoCloseable接口(包括实现了java.io.Closeable接口)的资源(如文件、流、网络连接等)的结构化方式。它可以确保在使用完资源后自动关闭它们,避免资源泄漏。
示例代码解释
我们可以使用try-with-resources语句来自动管理资源,确保它们在使用完毕后正确关闭,即使在发生异常的情况下。
下面是一个使用try-with-resources语句的例子,展示如何使用BufferedWriter写入文件,并确保资源在使用后自动关闭。
package org.example;
import java.io.*;
public class Buffer {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
bw.write("Hello, World!");
bw.newLine(); // 空一行
bw.write("newLine()");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
关键点
- 自动关闭资源:在try块中声明的资源(在此例中为BufferedWriter)在try块结束时会自动关闭,无需显式调用close()方法。这是在try块退出时,无论是正常退出还是由于异常退出,都会执行的。
- 减少冗余代码:try-with-resources语句减少了手动管理资源的冗余代码,使代码更简洁和易读。
- 异常处理:如果在使用资源的过程中抛出异常,try-with-resources语句仍会确保资源被关闭。这是通过自动调用资源的close()方法来实现的。
flush()方法的作用
虽然try-with-resources会在关闭BufferedWriter时自动调用flush(),但有时你可能希望在某些时刻强制将缓冲区中的数据写入文件。示例:
package org.example;
import java.io.*;
public class Buffer {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
bw.write("Hello, World!");
bw.newLine(); // 空一行
bw.write("newLine()");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,flush()方法会强制将缓冲区中的内容立即写入文件,这在需要确保数据在某个特定时刻被写入时是有用的,例如在实时日志记录或系统状态持久化时。
总结
- try-with-resources语句:简化资源管理,确保资源在使用后自动关闭。
- 自动调用close():try-with-resources会自动调用资源的close()方法,即使发生异常。
- 显式调用flush():在需要立即写入数据时,可以显式调用flush()方法,尽管在资源关闭时会自动刷新缓冲区。
注意事项
- 缓冲区大小:默认缓冲区大小一般是8KB,具体大小可以根据需求调整。如果进行大量小数据的读写操作,适当增大缓冲区大小可以提高性能。
- 资源管理:在使用BufferedReader和BufferedWriter时,务必在操作完成后关闭流,以释放系统资源。使用try-with-resources语句可以自动关闭流。
- 线程安全:BufferedReader和BufferedWriter不是线程安全的,如果多个线程同时访问同一个流,可能会导致数据不一致。可以使用适当的同步机制来保证线程安全。
- 高效读写:为了高效地读取和写入数据,缓冲机制是关键。通过减少实际I/O操作的次数,BufferedReader和BufferedWriter提供了显著的性能提升,特别是在处理大文件或频繁读写的场景下。
转载自开思通智网:https://www.opensnn.com/os/article/10000859
BufferedReader和BufferedWriter简介
BufferedReader和BufferedWriter简介
为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。BufferedReader用于加快读取字符的速度,BufferedWriter用于加快写入的速度
BufferedReader和BufferedWriter类各拥有8192个字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
BufferedReader
BufferedReader是为了提供读的效率而设计的一个包装类,它可以包装字符流。可以从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
构造方法
方法 描述
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
成员方法
方法 描述
int read() 读取单个字符。
int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
String readLine() 读取一个文本行。
long skip(long n) 跳过字符。
boolean ready() 判断此流是否已准备好被读取。
void close() 关闭该流并释放与之关联的所有资源。
void mark(int readAheadLimit) 标记流中的当前位置。
boolean markSupported() 判断此流是否支持 mark() 操作(它一定支持)。
void reset() 将流重置到最新的标记。
读取文件实例
读取文件: 一个字符一个字符的读取
int read()方法,每次可以读取到一个字符(以int 类型表示),不过因为返回的是int类型的,所以要强制类型转换成char类型才能打印该字符。
public static void printByFileReader(String filePath) throws IOException
{
BufferedReader reader=new BufferedReader(
new FileReader(filePath)
);
if(!reader.ready())
{
System.out.println("文件流暂时无法读取");
return;
}
int result=0;
while((result=reader.read())!=-1)
{
//因为读取到的是int类型的,所以要强制类型转换
System.out.print((char)result);
}
reader.close();
}
读取文件:一个数组一个数组的读取
int read(char[] cbuf, int off, int len)方法,每次读取len个字符放到字符数组cbuf中,从数组cbuf的下表off开始放,返回的是每次读取的字符个数。
public static void printByFileReaderChars(String filePath) throws IOException
{
BufferedReader reader=new BufferedReader(
new FileReader(filePath)
);
if(!reader.ready())
{
System.out.println("文件流暂时无法读取");
return;
}
int size=0;
char[] cbuf=new char[20];
while((size=reader.read(cbuf, 0, cbuf.length))!=-1)
{
System.out.print(new String(cbuf,0,size));
}
reader.close();
}
读取文件:一行一行的读取
String readLine()这个方法一次可以读取一个文本行,返回的直接就是这一行的字符串,如果读到行尾了就返回null。
public static void printByFileReaderLine(String filePath) throws IOException
{
BufferedReader reader=new BufferedReader(
new FileReader(filePath)
);
if(!reader.ready())
{
System.out.println("文件流暂时无法读取");
return;
}
int size=0;
String line;
while((line=reader.readLine())!=null)
{
System.out.print(line+"\n");
}
reader.close();
}
需要注意的是:reader.readLine()方法返回的一行字符中不包含换行符,所以输出的时候要自己加上换行符。
BufferedReader比FileReader高级的地方在于这个,FileReader能一次读取一个字符,或者一个字符数组。而BufferedReader也可以,同时BufferedReader还能一次读取一行字符串。同时,BufferedReader带缓冲,会比FileReader快很多。
但是FileReader使用项目的编码来读取解析字符,不能指定编码,可能会出现编码问题,如果要指定编码可以使用包装InputStreamReader的BufferedReader。这样兼顾效率和编码。
测试上述方法:
public static void main(String[] args) throws IOException
{
String fileutf8="utf8.txt";
String filegbk="gbk.txt";
//一个字符一个字符的读取
printByFileReader(filegbk);
System.out.println("\n---------------------------------------");
//一个字符数组一个字符数组的读取
printByFileReaderChars(filegbk);
System.out.println("\n---------------------------------------");
//一行一行的读取
printByFileReaderLine(filegbk);
System.out.println("#########################################");
//一个字符一个字符的读取
printByFileReader(fileutf8);
System.out.println("\n---------------------------------------");
//一个数组一个数组的读取
printByFileReaderChars(fileutf8);
System.out.println("\n---------------------------------------");
//一行一行的读取
printByFileReaderLine(fileutf8);
}
运行结果:
gbk file
这里是一句中文
---------------------------------------
gbk file
这里是一句中文
---------------------------------------
gbk file
这里是一句中文
#########################################
utf-8 file
杩欓噷鏄竴鍙ヤ腑鏂?
---------------------------------------
utf-8 file
杩欓噷鏄竴鍙ヤ腑鏂?
---------------------------------------
utf-8 file
杩欓噷鏄竴鍙ヤ腑鏂?
可以看到包装FileReader的BufferedReader在读取文件时候如果文件的编码和项目的编码不一样的时候,会出现乱。
乱码问题
使用包装InputStreamReader的BufferedReader读取文件
String file = "utf8.txt";
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file), "utf-8"));
char[] cbuf=new char[20];
int size;
while((size=reader.read(cbuf, 0, cbuf.length))!=-1)
{
System.out.println(new String(cbuf,0,size));
}
运行结果:
utf-8 file
这里是一句中文
这里要弄清楚的是BufferedReader只负责读到它的内部缓冲区中,而解码的工作是InputStreamReader完成的。
BufferedWriter
BufferedWriter的API:
构造函数:
方法 描述
BufferedWriter(Writer out) 创建一个缓冲字符输出流,使用默认大小的输出缓冲区
BufferedWriter(Writer out, int sz) 创建一个缓冲字符输出流,使用给定大小的输出缓冲区
成员方法
方法 描述
void write(int c) 写入单个字符。
void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
void write(String s, int off, int len) 写入字符串的某一部分。
void newLine() 写入一个行分隔符。
void close() 关闭此流,但要先刷新它。
void flush() 刷新该流的缓冲。
写文件实例
使用上述三个写方法写文件:一个字符一个字符的复制文件
public static void main(String[] args) throws IOException
{
BufferedWriter writer=new BufferedWriter(new FileWriter("静夜思.txt"));
char ch=''床'';
//写入一个字符
writer.write(ch);
String next="前明月光,";
char[] nexts=next.toCharArray();
//写入一个字符数组
writer.write(nexts,0,nexts.length);
//写入换行符
writer.newLine();//写入换行符
String nextLine="疑是地上霜。";
//写入一个字符串。
writer.write(nextLine);
//关闭流
writer.close();
}
运行结果,静夜思.txt:
床前明月光,
疑是地上霜。
应用:复制文本文件
逐个字符复制文件
static void copyByChar(String srcFile, String destFile) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(srcFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(destFile));
int ch=0;
//读取一个字符
while ((ch = reader.read()) != -1)
{
//写入一个字符
writer.write(ch);
}
reader.close();
writer.close();
}
逐个字符数组复制文件
static void copyByCharArray(String srcFile, String destFile) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(srcFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(destFile));
int size=0;
char[] cbuf=new char[20];
//读取一个字符数组
while ((size = reader.read(cbuf)) != -1)
{
//读入多少写入多少
writer.write(cbuf,0,size);
}
reader.close();
writer.close();
}
按行复制文件
static void copyByLine(String srcFile,String destFile) throws IOException
{
BufferedReader reader=new BufferedReader(new FileReader(srcFile));
BufferedWriter writer=new BufferedWriter(new FileWriter(destFile));
String line;
//BufferedReader读取一行的时候返回的字符串中不包括换行符
//如果有一行字符就返回该行字符串,没有就返回null
while((line=reader.readLine())!=null)
{
writer.write(line);
writer.newLine();//写换行符
}
reader.close();
writer.close();
}
需要注意的是,BufferedReader的readLine()读取一行的时候返回的字符串没有换行符,所以,复制的时候写文件是我们好多写入一个换行符,使用writer.newLine()方法即可。
测试:
public static void main(String[] args) throws IOException
{
String from = "gbk.txt";
String to = "gbk_copy.txt";
String to1 = "gbk_copy1.txt";
String to2 = "gbk_copy2.txt";
copyByChar(from, to);
copyByCharArray(from, to1);
copyByLine(from, to2);
}
源文件gbk.txt:
运行结果:
gbk_copy.txt
gbk file
这里是一句中文
gbk_copy1.txt
gbk file
这里是一句中文
gbk_copy2.txt
gbk file
这里是一句中文
bug:按行复制的时候多写换行符
细心的朋友可能发现,按行复制的时候,复制的文件会莫名其妙的在文件后面多了一个换行符。这是因为我们每次都在读到的字符串后面写一个换行符。
解决办法:在读到的字符串前面写换行符,这样出现新的问题,就是在文件开头多出了一个空行,所以加入控制语句,在第一行不写入换行符,第二行后再写。
static void copyByLine(String srcFile,String destFile) throws IOException
{
BufferedReader reader=new BufferedReader(new FileReader(srcFile));
BufferedWriter writer=new BufferedWriter(new FileWriter(destFile));
String line;
//BufferedReader读取一行的时候返回的字符串中不包括换行符
//如果有一行字符就返回该行字符串,没有就返回null
boolean flag=false;
while((line=reader.readLine())!=null)
{
if(!flag)
{
flag=true;
writer.write(line);
}
else
{
writer.newLine();//写换行符
writer.write(line);
}
}
reader.close();
writer.close();
}
这样复制的文件就不会多谢换行符了,保证复制的文件和源文件是一模一样的。
bug:乱码问题
因为我们使用的是包装FileReader的BufferedReader,包装FileWriter的BufferedWriter。所以读字符,写字符的时候使用的是默认的字符编码读写的。所以读写文件的时候会出现乱码,可以使用包装InputStreamReader的BufferedReader,包装OutputStreamWriter的BufferedWriter来复制文件,这样就可以支持各种字符编码。
实例:gbk编码的文件复制到utf8编码的文件中:
static void copyByLineEncoding(String srcFile, String srcEncoding, String destFile,
String destEncoding)
{
BufferedReader reader = null;
BufferedWriter writer = null;
try
{
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(srcFile), srcEncoding));
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(destFile), destEncoding));
char[] charArray = new char[512];
int size;
while ((size = reader.read(charArray, 0, charArray.length)) != -1)
{
writer.write(charArray, 0, size);
}
} catch (UnsupportedEncodingException | FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (writer != null)
{
try
{
writer.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
if (reader != null)
{
try
{
reader.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
main方法:
public static void main(String[] args) throws IOException
{
String from = "gbk.txt";
String to = "copyto_utf8.txt";
copyByLineEncoding(from,"gbk",to,"utf-8");
}
源文件gbk.txt(gbk编码):
gbk file
这里是一句中文
目标文件copyto_utf8.txt:
utf-8 file
杩欓噷鏄竴鍙ヤ腑鏂�
乱码是正常的,因为我们的工程目录用的gbk编码,把copyto_utf8.txt编码显示就好了:
utf-8 file
这里是一句中文
所以使用包装InputStreamReader的BufferedReader,包装OutputStreamWriter的BufferedWriter来复制文件的好处就是可以指定复制文件的时候使用的字符编码,例如上面的复制操作,从gbk编码的文件中读取,然后写入到utf8编码的文件中去。
————————————————
版权声明:本文为CSDN博主「蓝蓝223」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21808961/article/details/81561464
关于Java学习日志和19-1-IO流-BufferedReader的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于BufferedReader 和BufferedWriter、BufferedReader和BufferedInputStream之间的区别、BufferedReader和BufferedWriter、BufferedReader和BufferedWriter简介的相关信息,请在本站寻找。
本文标签: