java IO(五):字节流、字符流的选择规律

*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}

.hljs-comment,
.hljs-template_comment,
.diff .hljs-header,
.hljs-javadoc {
color: #998;
font-style: italic;
}

.hljs-keyword,
.css .rule .hljs-keyword,
.hljs-winutils,
.javascript .hljs-title,
.nginx .hljs-title,
.hljs-subst,
.hljs-request,
.hljs-status {
color: #333;
font-weight: bold;
}

.hljs-number,
.hljs-hexcolor,
.ruby .hljs-constant {
color: #099;
}

.hljs-string,
.hljs-tag .hljs-value,
.hljs-phpdoc,
.tex .hljs-formula {
color: #d14;
}

.hljs-title,
.hljs-id,
.coffeescript .hljs-params,
.scss .hljs-preprocessor {
color: #900;
font-weight: bold;
}

.javascript .hljs-title,
.lisp .hljs-title,
.clojure .hljs-title,
.hljs-subst {
font-weight: normal;
}

.hljs-class .hljs-title,
.haskell .hljs-type,
.vhdl .hljs-literal,
.tex .hljs-command {
color: #458;
font-weight: bold;
}

.hljs-tag,
.hljs-tag .hljs-title,
.hljs-rules .hljs-property,
.django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal;
}

.hljs-attribute,
.hljs-variable,
.lisp .hljs-body {
color: #008080;
}

.hljs-regexp {
color: #009926;
}

.hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.lisp .hljs-keyword,
.tex .hljs-special,
.hljs-prompt {
color: #990073;
}

.hljs-built_in,
.lisp .hljs-title,
.clojure .hljs-built_in {
color: #0086b3;
}

.hljs-preprocessor,
.hljs-pragma,
.hljs-pi,
.hljs-doctype,
.hljs-shebang,
.hljs-cdata {
color: #999;
font-weight: bold;
}

.hljs-deletion {
background: #fdd;
}

.hljs-addition {
background: #dfd;
}

.diff .hljs-change {
background: #0086b3;
}

.hljs-chunk {
color: #aaa;
}

#container {
padding: 15px;
}
pre {
border: 1px solid #ccc;
border-radius: 4px;
display: block;
background-color: #f8f8f8;
}
pre code {
white-space: pre-wrap;
}
.hljs,
code {
font-family: Monaco, Menlo, Consolas, ‘Courier New‘, monospace;
}
:not(pre) > code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
white-space: nowrap;
border-radius: 4px;
}
-->

字节流、字符流涉及的类比较多,比较容易混淆。因此,有必要针对何时使用字节流、何时使用字符流、何时使用Buffer类的流做一个归纳。要归纳它们,无需过多的语言,只需抓住它们的重点和特性即可。

在决定何时使用何种类时,以下几个问题需要考虑清楚。

  1. 是否有数据源、数据的流向是否有目标。

    • 数据源:表示输入,或称为读。可提供使用的两个父类为InputStream和Reader。
    • 有目标:表示输出,或称为写。可提供使用的两个父类为OutputStream和Writer。
  2. 应该使用字节流还是字符流?如果源或目标包含非ascii字符,则采用字符流。
  3. 源和目标是何种设备类型。
    • 源 :磁盘文件File,内存(字节/字符数组),键盘System.in,网络socket
    • 目标:磁盘文件File,内存(字节/字符数组),屏幕System.out,网络socket
  4. 是否需要使用BufferedReader/BufferedWriter?这需要考虑是否需要额外的特殊功能,包括操作行,字符集转换,使用缓冲区提高效率。字符集转换过程中涉及了字节流转换为字符流的过程,可能需要使用InputStreamReader和OutputStreamWriter作为转换的桥梁。

最后,需要知道的是对于使用BufferedReader的输入流,有时候可以考虑使用字符数组可能效果和性能更好。

以下是一个应用以上规律的需求示例:读取包含gbk简体中文的文件数据,并以utf-8编码复制到另一个文件中。

//1.有源有目标,且都是文件。 //2.读取和写入都包含中文字符,所以采用字符流。 //3.写入过程中需要转码,因此需要使用OutputStreamWriter。 //4.可以使用缓冲区功能提高效率。

import java.io.*;

public class CP {
    public static void main(String[] args) throws IOException {
        File src = new File("d:/myjava/a.txt");
        File dest = new File("d:/myjava/a_bak.txt");
        cp(src,dest);
    }

    public static void cp(File src,File dest) throws IOException {
        BufferedReader bufr = new BufferedReader(new FileReader(src));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest),"utf-8"));

        //按行读取

        String line = null;
        while((line=bufr.readLine())!=null) {
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }
        bufw.close();
    }
}

上述代码执行后,目标文件中的末尾将比源文件多一个空行,上述方法对这个问题不是很好解决。但如果使用字符数组来替代BufferedReader,则没有这样的问题,如下。

import java.io.*;

public class CP {
    public static void main(String[] args) throws IOException {
        File src = new File("d:/myjava/a.txt");
        File dest = new File("d:/myjava/a_bak.txt");
        cp(src,dest);
    }

    public static void cp(File src,File dest) throws IOException {
    FileReader fr = new FileReader(src);
    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest),"utf-8"));

    char[] buf = new char[1024];
    int len = 0;
    while ((len=fr.read(buf))!=-1) {
        bufw.write(buf,0,len);
        bufw.flush();
    }
    bufw.close();
    }
}

注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!

原文地址:https://www.cnblogs.com/f-ck-need-u/p/8159282.html

时间: 2024-08-25 03:20:24

java IO(五):字节流、字符流的选择规律的相关文章

IO 复习字节流字符流拷贝文件

/* 本地文件 URL 文件拷贝 *//*文本文件拷贝 可以通过 字符流,也可以通过字节流*/ /*二进制文件拷贝 只可以通过字节流*//* 希望这个例子能帮助搞懂 字符流与字节流的区别 */ import java.io.*; //in order to utilize stream object import java.util.*; // in order to utilize ArrayList import java.net.*; class Copy{ public static v

java IO(三):字符流

*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hljs-comment, .hljs-template_comment, .diff .hljs-header, .hljs-javadoc { color: #998; font-style: italic; } .hljs-keyword, .css .rule .hljs-keyword, .h

java io 学习之三 字符流的缓冲区

 /** 字符流的缓冲区 缓冲区的出现,提高了对数据的读写效率 对应的类: BufferedWriter BufferedReader 缓冲区要结合流才可以使用 缓冲区是在流的基础上对流的功能进行增强 软件的优化可以分为:设计优化和性能优化 设计优化:对代码进行重构,让代码实现更强的可扩展性和灵活性,复用性. 提高性能最常用的的手段是:缓冲区  线程池 BufferedWriter 构造方法摘要 BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输

Java——IO类,字符流读数据

body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(2n){background-co

io系列之字符流

java中io流系统庞大,知识点众多,作为小白通过五天的视频书籍学习后,总结了io系列的随笔,以便将来复习查看. 本篇为此系列随笔的第一篇:io系列之字符流. IO流 :对数据的传输流向进行操作,java中将这种操作行为本身封装为对象,以供使用. Input and Output java将io流对象都在IO包中.(java.IO.*) 分类: 按照数据种类分: 字节流 和 字符流, 按照数据流向分: 输出流 和 输入流. 字节流抽象类: InputStream OutputStream 字符流

Android笔记:利用InputStream和BufferedReader 进行字节流 字符流处理

通过socket获取字节流处理时最初使用的是BufferedReader和PrintWriter  这种方式在解析字符串时是比较方便的 但是在处理字节时不够方便最终还是回归到InputStream和OutputStream方式 不使用缓存直接使用字节流操作,一次传输的字节数据在300字节以内,目前没有测试差距会有多大. import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException;

IO-03字节流字符流

在程序中所有的数据都是以流的方式进行传输和保存的,程序需要数据的时候要使用输入流读取数据,而程序需要将一些数据保存起来则需要使用输出流来完成. 在JAVA.IO包中操作文件内容的主要有两大类:字节流,字符流,两类都分为输入和输出操作.在字节流中输出数据主要是使用OutputStream,输入主要使用InputStream,在字符流中输出主要使用Writer类完成,输入只要使用Reader类完成. 主要的操作流程如下: 使用FILE类打开一个文件 通过字节流或者字符流的子类,指定输出的位置. 进行

Java IO: 其他字节流(上)

作者: Jakob Jenkov 译者: 李璟([email protected]) 本小节会简要概括Java IO中的PushbackInputStream,SequenceInputStream和PrintStream.其中,最常用的是PrintStream,System.out和System.err都是PrintStream类型的变量,请查看Java IO: System.in, System.out, System.err浏览更多关于System.out和System.err的信息. P

JavaLearning:JAVA IO 之内存操作流

package org.fun.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; public class ByteArrayDemo { public static void main(String[] args) { String str = "helloworld";// 定义字符串,全部由小写字母组成 ByteArrayOutputStream bos = null;//