字节流与字符流的区别?

  字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?

  实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,如下图所示

  下面以两个写文件的操作为主进行比较,但是在操作时字节流和字符流的操作完成之后都不关闭输出流。

  案例1:使用字节流不关闭执行

package byteStream;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream; /**
* 操作字节流
* @author Administrator
* 不关闭输出流
*/
public class byteStreamDemo {
public static void main(String[] args) throws Exception { // 异常抛出, 不处理
// 第1步:使用File类找到一个文件
File f = new File("e:" + File.separator + "test"+File.separator+"test.txt"); // 声明File 对象
// 第2步:通过子类实例化父类对象
OutputStream out = null;
// 准备好一个输出的对象
out = new FileOutputStream(f);
// 通过对象多态性进行实例化
// 第3步:进行写操作
String str = "Hello World!!!";
// 准备一个字符串
byte b[] = str.getBytes();
// 字符串转byte数组
out.write(b);
// 将内容输出
// 第4步:关闭输出流
// out.close();
// 此时没有关闭
} }

  运行结果:

  此时没有关闭字节流操作,但是文件中也依然存在了输出的内容,证明字节流是直接操作文件本身的。而下面继续使用字符流完成,再观察效果。

  案例2:使用字符流不关闭执行

package byteStream;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer; /**
* 操作字符流
* @author Administrator
* 不关闭输出流
*/
public class WriterDemo01 {
public static void main(String[] args) throws Exception { // 异常抛出, 不处理
// 第1步:使用File类找到一个文件
File f = new File("e:" + File.separator +"test"+File.separator +"test2.txt");// 声明File 对象
// 第2步:通过子类实例化父类对象
Writer out = null;
// 准备好一个输出的对象
out = new FileWriter(f);
// 通过对象多态性进行实例化
// 第3步:进行写操作
String str = "Hello World!!!";
// 准备一个字符串
out.write(str);
// 将内容输出
// 第4步:关闭输出流
// out.close();
// 此时没有关闭
}
}

  运行结果:

  程序运行后会发现文件中没有任何内容,这是因为字符流操作时使用了缓冲区,而在关闭字符流时会强制性地将缓冲区中的内容进行输出,但是如果字符流没有关闭,则缓冲区中的内容是无法输出的,所以得出结论:字符流使用了缓冲区,而字节流没有使用缓冲区。

  缓冲区可以简单地理解为一段内存区域,一段特殊的内存。

  某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。

  在字符流的操作中,所有的字符都是在内存中形成的,在输出前会将所有的内容暂时保存在内存之中,所以使用了缓冲区暂存数据。

  如果想在不关闭时也可以将字符流的内容全部输出,则可以使用Writer类中的flush()方法完成。

  案例3:强制性清空缓冲区

package byteStream;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer; /**
* 操作字符流
* @author Administrator
* 不关闭输出流,使用flush(),强制清空缓冲区
*/
public class WriterDemo02 {
public static void main(String[] args) throws Exception { // 异常抛出不处理
// 第1步:使用File类找到一个文件
File f = new File("e:" + File.separator + "test"+File.separator+"test3.txt");// 声明File 对象
// 第2步:通过子类实例化父类对象
Writer out = null;
// 准备好一个输出的对象
out = new FileWriter(f);
// 通过对象多态性进行实例化
// 第3步:进行写操作
String str = "Hello World!!!";
// 准备一个字符串
out.write(str);
// 将内容输出
out.flush();
// 强制性清空缓冲区中的内容
// 第4步:关闭输出流
// out.close();
// 此时没有关闭
}
}

  程序运行结果:

  此时,文件中已经存在了内容,更进一步证明内容是保存在缓冲区的。这一点在读者日后的开发中要特别引起注意。

  使用字节流好还是字符流好? 

  学习完字节流和字符流的基本操作后,已经大概地明白了操作流程的各个区别,那么在开发中是使用字节流好还是字符流好呢? 回答是:使用字节流更好。

  在回答之前,先为读者讲解这样的一个概念,所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节流使用较为广泛。 字节流与字符流主要的区别是他们的的处理方式 。

流分类:

  Java的字节流

    InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先。

  Java的字符流

    Reader是所有读取字符串输入流的祖先,而writer是所有输出字符串的祖先。

  另外,由于InputStream,OutputStream,Reader,writer都是抽象类,所以不能直接new关键字。

  字节流是最基本的,所有的InputStream和OutputStream的子类都是主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化 。这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联。

  在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的。

  在字节流转化为字符流时,实际上就是byte[]转化为String,

  public String(byte bytes[], String charsetName)

  其中有一个关键的参数字符集编码,通常我们都省略了,系统就会用操作系统的lang。

  而在字符流转化为字节流时,实际上是String转化为byte[],

  byte[] String.getBytes(String charsetName) 也是一样的道理。

  至于java.io中还出现了许多其他的流,按主要是为了提高性能和使用方便,如BufferedInputStream,PipedInputStream等。

参考资料:

http://wjheye.iteye.com/blog/1041309

JAVA中的字节流与字符流的更多相关文章

  1. java中OutputStream字节流与字符流InputStreamReader 每一种基本IO流BufferedOutputStream,FileInputStream,FileOutputStream,BufferedInputStream,BufferedReader,BufferedWriter,FileInputStream,FileReader,FileWriter,InputStr

    BufferedOutputStream,FileInputStream,FileOutputStream,BufferedInputStream,BufferedReader,BufferedWri ...

  2. Java中的字节流,字符流,字节缓冲区,字符缓冲区复制文件

     一:创建方式 1.建立输入(读)对象,并绑定数据源 2.建立输出(写)对象,并绑定目的地 3.将读到的内容遍历出来,然后在通过字符或者字节写入 4.资源访问过后关闭,先创建的后关闭,后创建的先关闭 ...

  3. java IO之字节流和字符流-Reader和Writer以及实现文件复制拷贝

    接上一篇的字节流,以下主要介绍字符流.字符流和字节流的差别以及文件复制拷贝.在程序中一个字符等于两个字节.而一个汉字占俩个字节(一般有限面试会问:一个char是否能存下一个汉字,答案当然是能了,一个c ...

  4. Java 输入/输出——字节流和字符流

    1.流的分类 (1)输入流和输出流(划分输入/输出流时是从程序运行所在内存的角度来考虑的) 输入流:只能从中读取数据,而不能向其写入数据. 输出流:只能向其写入数据,而不能从中读取数据. 输入流主要由 ...

  5. java IO通过字节流,字符流 读出写入

    一:通过字节流操作数据的写入,读出 /** * 通过字节流写入和读出 * @param args */ public static String filePath = "G:" + ...

  6. java IO的字节流和字符流及其区别

    1. 字节流和字符流的概念    1.1 字节流继承于InputStream    OutputStream,    1.2 字符流继承于InputStreamReader    OutputStre ...

  7. JAVA基础之字节流与字符流

    个人理解: IO流就是将数据进行操作的方式,因为编码的不同,所以对文件的操作就产生两种.最好用字节流,为了方便看汉字等,(已经确定文字的话)可以使用字符流.每个流派也就分为输入和输出,这样就可以产生复 ...

  8. java基础(23):字节流、字符流

    1. 字节流 在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现在我们就要开始给文件中写数据,或者读取文件中的数据. 1.1 字节输出流OutputStream Out ...

  9. Java——I/O,字节流与字符流,BufferedOutputStream,InputStream等(附相关练习代码)

    I/O: I/O是什么? 在程序中,所有的数据都是以流的形式进行传输或者保存. 程序需要数据的时候,就要使用输入流读取数据. 程序需要保存数据的时候,就要使用输出流来完成. 程序的输入以及输出都是以流 ...

随机推荐

  1. zabbix install

    Auth: Jin Date: 20140714 用了5 6年的监控工具 http://zabbix.org/wiki/InstallOnCentOS_RHEL Server Install yum ...

  2. 原生JavaScript---正则表达式

    JavaScript 中正则的性能比想象中的低很多.能用字符串方法搞定的,尽量别用正则.------玉伯 抛开性能不谈,一起来看看正则表达式怎么用吧! 先看看JavaScript正则表达式中一些特殊字 ...

  3. mysql配置文件my.ini优化详解

    mysql 5.5.13参数说明:[client]character-set-server = utf8port = 3306socket = /data/mysql/3306/mysql.sock[ ...

  4. 在Mac中设置Ctrl+C/V进行复制/粘贴

    从Windows世界走入Mac世界,最让不习惯的是在Mac中“复制/粘贴”的快捷键是Command+C/V.而且Command键与C/V键靠得太近,只能用大拇指与食指进行操作,也让人不习惯.再加上远程 ...

  5. Activex 数字签名

    本次使用makecert的命令如下: makecert -sv online.pvk -n "CN=中国在线" -ss My -r -b 01/01/1900 -e 01/01/9 ...

  6. ASP.NET MVC:看 MVC 源码,学习:如何将 Area 中的 Controller 放到独立的程序集?

    背景 本文假设您已经熟悉了 ASP.NET MVC 的常规开发方式.执行模型和关键扩展点,这里主要说一下如何使用 ASP.NET MVC 的源代码解决一些问题. 如何将 Area 中的 Control ...

  7. [翻译] YLGIFImage 高效读取GIF图片

    YLGIFImage 高效读取GIF图片 https://github.com/liyong03/YLGIFImage Asynchronized GIF image class and Image ...

  8. 3DPrint ABS和PLA代码比较

    PLA ABS

  9. Python学习(六)模块

    Python 模块 模块定义 随着程序越来越庞大,需要分隔成几个文件:也需要能在不同文件中复用函数.类和变量,而不是拷贝代码.为了满足这些需要,Python提供了模块. 简单来说,模块就是一个保存了P ...

  10. OpenMP 中的线程任务调度

    OpenMP中任务调度主要针对并行的for循环,当循环中每次迭代的计算量不相等时,如果简单地给各个线程分配相同次数的迭代,则可能会造成各个线程计算负载的不平衡,影响程序的整体性能. 如下面的代码中,如 ...