我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaIO BufferedReader和BufferedWriter使用及说明

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaIO 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 class="lazy" data-srcFile, String destFile) throws IOException
{
    BufferedReader reader = new BufferedReader(new FileReader(class="lazy" data-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 class="lazy" data-srcFile, String destFile) throws IOException
{
    BufferedReader reader = new BufferedReader(new FileReader(class="lazy" data-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 class="lazy" data-srcFile,String destFile) throws IOException
{
    BufferedReader reader=new BufferedReader(new FileReader(class="lazy" data-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 class="lazy" data-srcFile,String destFile) throws IOException
{
    BufferedReader reader=new BufferedReader(new FileReader(class="lazy" data-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 class="lazy" data-srcFile, String class="lazy" data-srcEncoding, String destFile,
        String destEncoding)
{
    BufferedReader reader = null;
    BufferedWriter writer = null;
    try
    {
        reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(class="lazy" data-srcFile), class="lazy" data-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编码的文件中去。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaIO BufferedReader和BufferedWriter使用及说明

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaIO BufferedReader和BufferedWriter使用及说明

这篇文章主要介绍了JavaIO BufferedReader和BufferedWriter使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-26

sql中的if和else使用及说明

目录sql中的if和elseIF表达式IF(expr1,expr2,expr3)IFNULL(expr1,expr2)IF ELSE 做为流程控制语句使用sql中的if和elsemysql的IF既可以作为表达式用,也可在存储过程中作为流程
2022-11-28

ES6数组some()和every()的使用及说明

这篇文章主要介绍了ES6数组some()和every()的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-16

vue-jsonp的使用及说明

这篇文章主要介绍了vue-jsonp的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-08

js中的WebSocket使用及说明

WebSocket是一种实时、低延迟的通信协议,允许客户端与服务器之间双向数据交换,弥补了传统HTTP请求-响应模型的局限性。它具有实时通信、低延迟、双向通信和低开销的优点,广泛用于聊天、实时数据流、多人游戏、物联网和协作工具等应用场景。要使用WebSocket,需要建立连接,收发消息,并使用API管理连接,包括open、send、close、onmessage、onerror等方法和事件。
js中的WebSocket使用及说明
2024-04-02

关于vue.extend的使用及说明

这篇文章主要介绍了关于vue.extend的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-03-06

vue中关于$emit和$on的使用及说明

这篇文章主要介绍了vue中关于$emit和$on的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

numpy之sum()的使用及说明

这篇文章主要介绍了numpy之sum()的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-03

vue3中Vant的使用及说明

这篇文章主要介绍了vue3中Vant的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-16

关于promise.all()的使用及说明

这篇文章主要介绍了关于promise.all()的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

C#中Stopwatch的使用及说明

这篇文章主要介绍了C#中Stopwatch的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-25

PyTorch中grid_sample的使用及说明

这篇文章主要介绍了PyTorch中grid_sample的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-01

Keras中Conv1D的使用及说明

这篇文章主要介绍了Keras中Conv1D的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-15

Python-apply(lambdax:)的使用及说明

这篇文章主要介绍了Python-apply(lambdax:)的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-01

vueantdForm表单的使用及说明

这篇文章主要介绍了vueantdForm表单的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

关于StringUtils.isBlank()的使用及说明

这篇文章主要介绍了关于StringUtils.isBlank()的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-19

c++的virtual和override作用及说明

这篇文章主要介绍了c++的virtual和override作用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录