字节流能不能一行行的读取数据? 怎样设置字符流与字节流读取的大小?

java处理文件的类里面,stream结尾都是采用字节流,reader和writer结尾都是采用字符流。两者的区别就是读写的时候一个是按字节读写,一个是按字符。&
字符流的底层就是字节流。而字符流主要是读取文本文件内容的,可以一个字符一个字符的读取,也可以一行一行的读取文本文件内容。而字节流读取单位为byte.byte作为计算机存储最基本单位,可以用字节流来读取很多其他格式的文件,比如图片视频等等。基于B/S和C/S的都可以采用字节流的形式。在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。只是读写文件,和文件内容无关的,一般选择字节流。&(注:除了字符和字节流之外,java还有一种叫对象流。有兴趣可以去查API学习一下。)
字节流就是按照字节来进行传输,字符流是按照字符来传输.最基本的是字节流,字符流可以说是对字节流的一个包装流.比如你知道了一个字符是8个字节,那么你让字节流一次传输8个字节,那不就相当于一次传输一个字符,也就是字符流了。
字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,如图
下面以两个写文件的操作为主进行比较,但是在操作时字节流和字符流的操作完成之后都不关闭输出流。范例:使用字节流不关闭执行
// 通过字节流 写文件
public static void ByteWrite() {
File file = new File("d:\\test\\test.txt");
OutputStream outputStream = new FileOutputStream(file);
String textString = "Hello World!!!";
byte[] data = textString.getBytes();
outputStream.write(data);
//outputStream.close();
} catch (IOException e) {
System.out.println("字节流写入文件出错。");
e.printStackTrace();
程序运行结果:
&此时没有关闭字节流操作,但是文件中也依然存在了输出的内容,证明字节流是直接操作文件本身的。而下面继续使用字符流完成,再观察效果。范例:使用字符流不关闭执行
// 通过字符流 写文件
public static void StringWrite() {
File file = new File("d:\\test\\test.txt");
FileWriter writer = new FileWriter(file);
String textString = "Hello World!!!";
writer.write(textString);
// writer.flush();
// writer.close();
} catch (IOException e) {
System.out.println("字符流写入文件出错.");
e.printStackTrace();
程序运行结果:
程序运行后会发现文件中没有任何内容,这是因为字符流操作时使用了缓冲区,而&& 在关闭字符流时会强制性地将缓冲区中的内容进行输出,但是如果程序没有关闭,则缓冲区中的内容是无法输出的,所以得出结论:字符流使用了缓冲区,而字节流没有使用缓冲区。提问:什么叫缓冲区?在很多地方都碰到缓冲区这个名词,那么到底什么是缓冲区?又有什么作用呢?回答:缓冲区可以简单地理解为一段内存区域。可以简单地把缓冲区理解为一段特殊的内存。某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。在字符流的操作中,所有的字符都是在内存中形成的,在输出前会将所有的内容暂时保存在内存之中,所以使用了缓冲区暂存数据。如果想在不关闭时也可以将字符流的内容全部输出,则可以使用Writer类中的flush()方法完成。
提问:使用字节流好还是字符流好?学习完字节流和字符流的基本操作后,已经大概地明白了操作流程的各个区别,那么在开发中是使用字节流好还是字符流好呢?回答:使用字节流更好。在回答之前,先为读者讲解这样的一个概念,所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节流使用较为广泛。字节流与字符流主要的区别是他们的的处理方式流分类: 1.Java的字节流 && InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先。 2.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等
阅读(...) 评论()IO流之字节流和字符流详解_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
IO流之字节流和字符流详解
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩15页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢java基础(10)
一,概述:
流的介绍:流的概念源于Unix中管道的概念,管道是一条不间断的流,用来实现程序或者进程间的通信,或读写外围设备,外部文件等。一个流必须有源端和目的端,他们可以实现进程或者进程间的通信,或读写外围设备迈步文件等。
流的方向是重要的,根据流的方向,流可分为两类:输入流和输出流。用户可以从输入流中读取信息,但不能写它。相反,对输出流,只能往输入流写,而不能读它。实际上,流的源端和目的端可简单地看成是字节的生产者和消费者,对输入流,可不必关心它的源端是什么,只要简单地从流中读数据,而对输出流,也可不知道它的目的端,只是简单地往流中写数据。&
& & & 形象的比喻——水流 ,文件======程序 ,文件和程序之间连接一个管道,水流就在之间形成了,自然也就出现了方向:可以流进,也可以流出.便于理解,这么定义流: 流就是一个管道里面有流水,这个管道连接了文件和程序。
二,流的分类:
1,java.io包中的类对应两类流:
一类流直接从指定的位置(如磁盘文件或内存区域)读或写,这类流称为结点流(node stream),
其它的流则称为过滤器(filters)。过滤器输入流往往是以其它输入流作为它的输入源,经过过滤或处理后再以新的输入流的形式提供给用户,过滤器输出流的原理也类似。
定义流: 流就是一个管道里面有流水,这个管道连接了文件和程序。
2,Java的常用输入、输出流:
java.io包中的stream类根据它们操作对象的类型是字符还是字节可分为两大类: 字符流和字节流。
输入流:InputStream(字节流),Reader(字符流)。输出流:OutputStream(字节流),Writer(字符流)。
三,字符流介绍:
1,字节流不能操作Unicode字符,由于Java采用16位的Unicode字符,即一个字符占16位,所以要使用基于字符的输入输出操作。所以创造了字符流,以提供直接的字符输入输出的支持。字符流处理的单元为
2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串。
2,字符流主要是用来处理字符的。Java采用16位的Unicode来表示字符串和字符,对应的字符流按输入和输出分别称为reader和writer。专门用于操作的否是字符数据的流对象。
3,Reader:
用于读取字符流的抽象类,子类必须实现的方法只有:reader(char[],int,int)和close()。read():读取单个字符并返回,read(char[]):将数据读取到数组中,并返回读取的个数。
4,Writer:
写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
5,FileReader:
用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。FileReader 用于读取字符流。要读取原始字节流,请考虑使用FileInputStream。
6,FileWriter
用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。
复制文本文件实例:
import java.io.FileNotFoundE
import java.io.FileR
import java.io.FileW
import java.io.IOE
public class CopyTextTest {
public static void main(String[] args) throws IOException {
练习:复制文本文件:
使用字符流,操作的为文件,涉及硬盘,默认编码。
使用fileReader
和FileWriter。
copyTextFile();
private static void copyTextFile() throws IOException {
//复制时先明确源文件和目的
FileReader fr = new FileReader(&e:\\file.txt&);
FileWriter fw = new FileWriter(&e:\\fw.txt&);
//该方法循环效率低:
/*int ch = 0;
while((ch=fr.read())!=-1){
fw.write(ch);
//自定义缓冲区数组,字符数组。此方法效率较高:
char[] buf = new char[1024];//一个字符两个字节,开辟了2k个大小的数组char[]。
int len=0;
while((len=fr.read(buf))!=-1){
fw.write(buf,0,len);
fw.write(buf);
fr.close();
fw.close();
7,BufferedReader和BufferedWriter:
缓冲区的原理:
1,使用了底层流对象从具体设备获取数据,并将存储到缓冲区中的数组内。
2,可以通过缓冲区的read方法,从缓冲区中来获取具体的字符数据。
3,如果用read()方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,另一个容器中临时存储的数据准成字符串返回,就形成了readline()功能。
import java.io.BufferedR
import java.io.BufferedW
import java.io.F
import java.io.FileNotFoundE
import java.io.FileR
import java.io.FileW
public class CopyFileByBuffer {
//通过缓冲区复制一个.java文件
public static void main(String[] args) throws Exception {
BufferedReader bufr =
BufferedWriter bufw =
bufr = new BufferedReader(new FileReader(&e:\\java\\ThreadDemo.java&));
bufw = new BufferedWriter(new FileWriter(new File(&e:\\&,&ThreadDemo.java&)));
String line =
while((line=bufr.readLine())!=null){
bufw.write(line);
bufw.flush();
四,字节流介绍:
1,字节流:字节流就是存储类的二进制原始信息,不需要翻译。字节流处理单元为
1 个字节,操作字节和字节数组。
2,InputStream 和 OutputStream 是两个 abstact 类,对于字节为导向的 stream 都扩展这两个鸡肋(基类 ^_^ )。
outputStream:输出字节流的超类,1,操作的数据都是字节,2,定义了输出字节流的基本共性功能,输出流中定义都是些write方法,它可以操作字节数组write(byte[]),操作单个字节write(byte)。
InputStream:字节输入流的超类。
1,常见功能,
int read():读取一个字节并返回。没有字节则返回-1。
int read(byte[]):读取一定量的字节数,并存储到字节数组中。返回读取到的字节数。
3,FileInputStream和FileOutputStream:
这两个类属于结点流,第一个类的源端和第二个类的目的端都是磁盘文件,它们的构造方法允许通过文件的路径名来构造相应的流。如:&FileInputStream infile = new FileInputStream(&myfile.dat&);FileOutputStream outfile = new FileOutputStream(&results.dat&);要注意的是,构造FileInputStream,
对应的文件必须存在并且是可读的,而构造FileOutputStream时,如输出文件已存在,则必须是可覆盖的。
代码实例:
&pre name=&code& class=&java&&package F
import java.io.F
import java.io.FileInputS
import java.io.FileNotFoundE
import java.io.FileOutputS
import java.io.IOE
public class FileCopyTest {
//复制文件练习:
public static void main(String[] args) throws IOException {
/*//1,明确源和目的
File srcFile = new File(&e:\\java\\car.java&);//可以复制音乐文件
File destFile = new File(&e:\\java.txt&);
//2,明确字节流
输入流和源相关联,输出流和目的关联。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//3,使用输入流的读取方式读取字节,并将字节写入到目的中.一次读取一个字节,并写入一次一个字节。
int ch = 0;
while ((ch = fis.read())!=-1){
fos.write(ch);
//自定义缓冲数组复制文件:
/*//1,明确源和目的
File srcFile = new File(&e:\\java\\car.java&);//可以复制音乐文件
File destFile = new File(&e:\\java.txt&);
//2,明确字节流
输入流和源相关联,输出流和目的关联。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//定义一个缓冲区:
byte[] buf = new byte[1024];//一次读取1024个字节,可以改变数字大小。
int len = 0;
while ((len=fis.read(buf))!=-1){
fos.write(buf, 0, len);//将数组中的指定长度的数据写入到输出流中。
//4,关闭流资源。
fos.close();*/
FileInputStream fis = new FileInputStream(&g:\\图片素材\\df.jpg&);
byte[] buf = new byte[fis.available()];//定义一个刚刚好的数组,文件过大容易溢出
fis.read(buf);
String str = new String(buf);
System.out.println(str);
fis.close();
4.BufferedInputStream和BufferedOutputStream:
它们是过滤器流,其作用是提高输入输出的效率。DataInputStream和DataOutputStream这两个类创建的对象分别被称为数据输入流和数据输出流。这是很有用的两个流,它们允许程序按与机器无关的风格读写Java数据。所以比较适合于网络上的数据传输。这两个流也是过滤器流,常以其它流如InputStream或OutputStream作为它们的输入或输出。
五,使用规律:
IO流中对象的使用规律总结:
解决问题时(处理设备上的数据时)到底该用哪一个对象?
1,明确要操作的数据是数据源还是数据目的。
若是数据源:则能用的:InputStream &Reader。(读数据)
若是目的:OutputStream &writer(写数据)
先根据需求,明确了要读还是要写。
2,要操作的数据的设备上的数据是字节还是文本?
源数据为字节:InputStream
源数据为文本:reader
目的数据为字节:OutputStream
目的数据问文本:Writer
3,已经明确体系开始寻找要使用的对象:
明确数据所在具体设备?
硬盘:文件,File开头。
内存:数组,字符串,常用。
键盘:System.in
网络:Socket(插座)
目的设备:
硬盘:文件,File开头。
内存:数组,字符串,常用。
屏幕:System.Out
网络:Socket
完全可以明确具体要使用哪个流对象。
4,是否需要额外功能?
额外功能:
是否需要转换?需要,则用转换流。InputStreamReader,OutputStream
高效?需要则用缓冲区对象。BufferedXXX
有多个源吗?序列流。SequenceInputStream
对象需要序列化吗?ObjectInputStream,ObjectOutputStream
需要操作基本类型数据保证字节原样性吗?DataOutputStream &DataInputStream。
源和目的都是内存的流对象:
字节流:ByteArrayInputStream, ByteArrayOutputStream
字符流:CharArrayReader & CharArrayWriter
StringReader & StringWriter
原理其实通过流的read,write方法对数组以及字符串进行操作。
关闭这些流都是无效的,因为并未调用系统资源,不需要抛出IOException。&&
六,细节:
1,OutputStreamWriter:是字符流通向字节流的桥梁:可以使用指定的charSet将要写入流中的字符编码成字节。他的作用就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。
2,flush和close区别:
flush:将流中的缓冲区缓冲的数据刷新到目的地,刷新后,流还可以继续使用。
close:关闭资源,但在关闭之前会将缓冲区的数据先刷新到目的地,然后再关闭流,流不可以再使用。
写入数据多,一定要一边写一遍刷新,最后一遍可以不刷新,由close完成刷新并关闭。
字节流操作的是字节数组,字符流操作的是字符数组。
3,继承关系:OutputStreamWriter:
--FileWriter:
&InputStreamReader:
--FileReader:
父类和子类功能区别:
osw和isr是字符和字节的桥梁:也可以称之为转换流。
转换流原理:字节流+编码表。
Fw和Fr最为子类,仅作为操作字符文件的便捷类存在,当操作的字符文件,使用的是默认编码表时,可以不用父类,而直接用子类就完成操作了,简化了代码。
InputStreamReader isr = new InputStreamReader(new FileInputStream(&sds.txt&));//使 用了默认编码表
InputStreamReader isr = new InputStreamReader(new FileInputStream(&sds.txt&),“gbk”);//指定编码表为gbk
FileReader fr = new FileReader(&a.txt&);//不能指定编码变,只能使用默认编码表,与上面两句意思一样。最为便捷。
一旦要指定gdk其他编码时,绝对不能使用子类,必须使用字符转换流。
当操作的是文件,并使用的是默认编码时,使用子类。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38817次
积分:1029
积分:1029
排名:千里之外
原创:57篇
转载:16篇
(1)(8)(7)(5)(4)(6)(6)(2)(2)(2)(2)(7)(2)(10)(11)

我要回帖

更多关于 字符流与字节流 的文章

 

随机推荐