中易网

java里字符流 字节流和序列化的区别?

答案:5  悬赏:20  
解决时间 2021-03-24 11:28
java里字符流 字节流和序列化的区别?
最佳答案
Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。
Java 内用 Unicode 编码存储字符,字符流处理类负责将外部的其他编码的字符流和 java 内 Unicode 字符流之间的转换。而类 InputStreamReader 和 OutputStreamWriter 处理字符流和字节流的转换。字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。

( 一 )以字节为导向的 stream------InputStream/OutputStream
InputStream 和 OutputStream 是两个 abstact 类,对于字节为导向的 stream 都扩展这两个鸡肋(基类 ^_^ ) ;
1、 InputStream

1.1
ByteArrayInputStream -- 把内存中的一个缓冲区作为 InputStream 使用 .
construct---
(A)ByteArrayInputStream(byte[]) 创建一个新字节数组输入流( ByteArrayInputStream ),它从指定字节数组中读取数据( 使用 byte 作为其缓冲区数组)
(B)---ByteArrayInputStream(byte[], int, int) 创建一个新字节数组输入流,它从指定字节数组中读取数据。
---mark:: 该字节数组未被复制。
1.2
StringBufferInputStream -- 把一个 String 对象作为 InputStream .
construct---
StringBufferInputStream(String) 据指定串创建一个读取数据的输入流串。

注释:不推荐使用 StringBufferInputStream 方法。此类不能将字符正确的转换为字节。
同 JDK 1.1 版中的类似,从一个串创建一个流的最佳方法是采用 StringReader 类。
1.3
FileInputStream -- 把一个文件作为 InputStream ,实现对文件的读取操作
construct---
(A)FileInputStream(File name) 创建一个输入文件流,从指定的 File 对象读取数据。
(B)FileInputStream(FileDescriptor) 创建一个输入文件流,从指定的文件描述器读取数据。
(C)-FileInputStream(String name) 创建一个输入文件流,从指定名称的文件读取数据。
method ---- read() 从当前输入流中读取一字节数据。
read(byte[]) 将当前输入流中 b.length 个字节数据读到一个字节数组中。
read(byte[], int, int) 将输入流中 len 个字节数据读入一个字节数组中。
1.4
PipedInputStream :实现了 pipe 的概念,主要在线程中使用 . 管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。
construct---
PipedInputStream() 创建一个管道输入流,它还未与一个管道输出流连接。
PipedInputStream(PipedOutputStream) 创建一个管道输入流 , 它已连接到一个管道输出流。
1.5
SequenceInputStream :把多个 InputStream 合并为一个 InputStream . “序列输入流”类允许应用程序把几个输入流连续地合并起来,
并且使它们像单个输入流一样出现。每个输入流依次被读取,直到到达该流的末尾。
然后“序列输入流”类关闭这个流并自动地切换到下一个输入流。
construct---
SequenceInputStream(Enumeration) 创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。
SequenceInputStream(InputStream, InputStream) 创建一个新的序列输入流,初始化为首先 读输入流 s1, 然后读输入流 s2 。

2、 OutputSteam

2.1
ByteArrayOutputStream : 把信息存入内存中的一个缓冲区中 . 该类实现一个以字节数组形式写入数据的输出流。
当数据写入缓冲区时,它自动扩大。用 toByteArray() 和 toString() 能检索数据。
constructor
(A)--- ByteArrayOutputStream() 创建一个新的字节数组输出流。
(B)--- ByteArrayOutputStream() 创建一个新的字节数组输出流。
(C)--- ByteArrayOutputStream(int) 创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。
toString(String) 根据指定字符编码将缓冲区内容转换为字符串,并将字节转换为字符。
write(byte[], int, int) 将指定字节数组中从偏移量 off 开始的 len 个字节写入该字节数组输出流。
write(int) 将指定字节写入该字节数组输出流。
writeTo(OutputStream) 用 out.write(buf, 0, count) 调用输出流的写方法将该字节数组输出流的全部内容写入指定的输出流参数。
2.2
FileOutputStream: 文件输出流是向 File 或 FileDescriptor 输出数据的一个输出流。
constructor
(A)FileOutputStream(File name) 创建一个文件输出流,向指定的 File 对象输出数据。
(B)FileOutputStream(FileDescriptor) 创建一个文件输出流,向指定的文件描述器输出数据。
(C)FileOutputStream(String name) 创建一个文件输出流,向指定名称的文件输出数据。
(D)FileOutputStream(String, boolean) 用指定系统的文件名,创建一个输出文件。
2.3
PipedOutputStream: 管道输出流是指一个通讯管道的发送端。一个线程通过管道输出流发送数据,
而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。
constructor
(A)PipedOutputStream() 创建一个管道输出流,它还未与一个管道输入流连接。
(B)PipedOutputStream(PipedInputStream) 创建一个管道输出流,它已连接到一个管道输入流。

( 二 )以字符为导向的 stream Reader/Writer
以 Unicode 字符为导向的 stream ,表示以 Unicode 字符为单位从 stream 中读取或往 stream 中写入信息。
Reader/Writer 为 abstact 类
以 Unicode 字符为导向的 stream 包括下面几种类型:
1. Reader

1.1
CharArrayReader :与 ByteArrayInputStream 对应此类实现一个可用作字符输入流的字符缓冲区
constructor
CharArrayReader(char[]) 用指定字符数组创建一个 CharArrayReader 。
CharArrayReader(char[], int, int) 用指定字符数组创建一个 CharArrayReader
1.2
StringReader : 与 StringBufferInputStream 对应其源为一个字符串的字符流。
StringReader(String) 创建一新的串读取者。
1.3
FileReader : 与 FileInputStream 对应
1.4
PipedReader :与 PipedInputStream 对应

2. Writer

2.1 CharArrayWrite : 与 ByteArrayOutputStream 对应
2.2 StringWrite :无与之对应的以字节为导向的 stream
2.3 FileWrite : 与 FileOutputStream 对应
2.4 PipedWrite :与 PipedOutputStream 对应

3、两种不同导向的 stream 之间的转换
3.1
InputStreamReader 和 OutputStreamReader :
把一个以字节为导向的 stream 转换成一个以字符为导向的 stream 。
InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。
InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。
为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
例如: // 实现从键盘输入一个整数
view plaincopy to clipboardprint?
String s = null;
InputStreamReader re = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(re);
try {
s = br.readLine();
System.out.println("s= " + Integer.parseInt(s));
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (NumberFormatException e)// 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
{
System.out.println(" 输入的不是数字 ");
}
String s = null; InputStreamReader re = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(re); try { s = br.readLine(); System.out.println("s= " + Integer.parseInt(s)); br.close(); } catch (IOException e) { e.printStackTrace(); } catch (NumberFormatException e)// 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。 { System.out.println(" 输入的不是数字 "); }

InputStreamReader(InputStream) 用缺省的字符编码方式,创建一个 InputStreamReader 。
InputStreamReader(InputStream, String) 用已命名的字符编码方式,创建一个 InputStreamReader 。

OutputStreamWriter 将多个字符写入到一个输出流,根据指定的字符编码将多个字符转换为字节。
每个 OutputStreamWriter 合并它自己的 CharToByteConverter, 因而是从字符流到字节流的桥梁。

(三)Java IO 的一般使用原则:
一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三、按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四、按数据格式分:
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类
五、按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类
六、特殊需要:
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
首先,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第 1 点
第四,数据来源(
全部回答
所谓serialization叫做 鳞次节比。别听那些小学语文不及格的说什么序列化。

你已知其一,
其二是:
请问:要保存 一个 对象的图(graph),或者 对象层次树结构之类的东东,你要如何做?
这就是serialization的约定。
只是这个约定是别人定义好的格式。
其实你自己另外处理,也一样。追答
追问:你说的我没明白 - - 还是直接回答我的问题,这样我好理解
请问用字节流能传中文吗?
为了保存对象的结构所以用序列化,这个到时明白点了,那我传的不是对象,是一堆文字保存到硬盘里,这还需要什么格式吗?不用序列化能不能直接传字符流保存啊???
追答:当然可以。

如果是文字,核心是bytes(我叫它为卦,八卦的卦,八卦了一下)方式,
但是实际上还有不同的编码格式,比如utf,gb等等
追问:编码格式忽略不管它,我就说如果传输的是文字,还需要序列化吗?比如聊天,双方打字之间的传送,需要序列化吗 ?
追答:不是忽略,是你必须选择一种编码方式。
知道你说的是文字。文字什么都不是。对于机器而言。
这些数字需要你的格式,才能被你自己使用。
追问:好吧,按你说的现在选择GBK编码了,然后是直接能保存文字到硬盘了吗,还是保存前先来个序列化,然后在保存?
现在就说下,保存字符串和序列化有关吗?
追答:真有点晕了。你不是这点有点明白了吗?
直接保存的这种处理方式本来就是某种形式的serialization。
而java的serialization也是一种特殊的serialization,而且这种方式中包含一个文字处理部分:就是utf8的格式。

一大一小,能区分,是吧。

既然都是,
只要那个合适,就用哪个,不就得了。
是java虚拟机的事!JAVA的运行机制你应该学习过吧!
他存的可不是直接存到计算机上的
我近期也是在研究这个问题
字节流是比较通用的一种读取方式 基本上任何的文本形式都可以读取
字符流一般是对于中文文本的处理 比如音频啊什么的 他就处理不了了 这里就需要字节流的处理
但是自我感觉还是字符流还用一点 最起码的是读取的方法简单一点 一般情况下 我们读取的文本文件也都是中文的吧
至于序列化其实不用也是可以 一样可以保存 但是那样保存的话要麻烦点 没有序列化简单
反序列话就是 从内存在读取了
字节流可以序列化任何文件,包括图片音频等等,字符流只能对文字操作,比如txt文件,字节流序列化后的保存的文件时二进制文件,比如先写入一段文字,又写入一张照片,使其存储方便,且其他软件无法识别,只有按照写入的顺序序列化读取才可以识别,能够起到加密的作用。字符流生成的文件,用记事本即可看到内容。
比如你写“大家好”,字节流打开后是乱码,字符流打开则是文字,不必用序列化的方式读取即可阅读到内容。
序列化的好处就是一次可以写入一个对象,使其可以读取恢复,方便数据传输,比如服务器非即时的与客户端传递数据,现将其序列化存储,再用客户端以对象的方式读取,对于封装数据会很方便。
以上均为个人见解,希望对你有所帮助。追答
追问:我好像明白了,就是说字符流和字节流都是一种格式,一般本文都是字符流格式的,如果用文本打开用字节流保存的内容就是乱码,因为保存时候你没有按文本的要求格式保存,所以必然是乱码。那序列化就是一种加密的字节流格式,也就是保存时候,先序列化变成字节流保存,等读取到内存反序列化,把字节流再变成字符流?
是这样理解嘛-。-
追答:也不能说是两种格式,字符只是按照某种约定一次性处理N个字节进行编码,从而可以文本显示,字节流则不管是什么都按单个字节处理,所以文本等任何软件都无法读取,只有按照你写入之前的约定进行编码才能读取内容。序列化的理解嘛,你就把它认为是java允许将一个对象写入文件的约定,也就是规则,因为对象中有各种属性方法,需要将这些组织成一个对象,这也就是规则,读取时再按照这个规则读取,就可以还原了。至于字符流字节流跟序列化没有关系。
追问:我感觉还是有点关系的,序列化的目的就是为了把对象编成字节流,如果不序列化,那传出去的就是字符流了或者没有秩序的字节流,这样的话下次读取的时候,也是没有秩序的字节流,这样运行的时候java虚拟机就影响效率了。所以序列化可以理解为一种编码和解码的东西,专门为特定格式比如对象,进行编码和解码用的。但终究到底在计算机里还是二进制0和1,那就是字节流.
追答:如果不序列化,是没办法将一个对象持久化的,只能逐一处理对象的属性,读取时再逐一读取,新建对象,并赋值,如果这个对象中有一个属性是另一个类,那么还要将这个类的属性逐一处理,如此反复下去。。。岂不麻烦。序列化就是干这个用的,至于选择字符流可能会显示文本,选择字节流可以加密,完全是另一回事了。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
曲靖市有那些酒店正在招聘中?
九州风神玄冰400和超频三红海至尊哪个散热器
空调移动重装里外机都有工作但制冷下不制冷了
易通通信怎么去啊,有知道地址的么
西安青海自驾游攻略,请资深驴友介绍下。
有哪位了解楼梯装修面积怎么算?
从莘县到济南东站有车吗?聊城有到济南东站的
离婚后贷款买房要向银行提供什么知识专题
腰部总感到酸痛,长期带远红外磁疗护腰好吗
汽车空调清洗多少钱一次
形容乐于向学问或地位比自己差的人学习,而不
松江西林小区怎么去松江新理想广场
王者荣耀白求凰多少点券
用毫不在意,吓唬,大发雷霆,造句
为什么我家电脑屏幕显示,超出信号范围
推荐资讯
什么叫设计方案
青岛食品代理进口报关有没有推荐的靠谱的公司
求天涯右岸一路同行的一篇帖子,《酒肉朋友的
车牌号后面hv不好吗
胖子面食馆在哪里啊,我有事要去这个地方
康师傅冰红茶是国内冰茶市场的老大吗?
2016全球流行音乐金榜怎么投票
理想如同什么它怎样我们什么的什么
有没有三天赚1万的方法
《美少女战士》中小兔和小卫是怎么在一起的?
葱油千层饼
顺丰小时工招聘信息,现在还在招吗
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?