j2se----流

[code]
InputStream旗下有

FileInputStream ----从文件读
PipedInputStream ---从管道读
ByteArrayInputStream --从内存数组读

SequenceInputStream
StringBufferInputStream --从字符缓冲区读

FilterInputStream-------其中他的旗下有
DataInputStream
ObjectInputStream
BufferedInputStream
PushbackInputStream ----支持回卷,也就是读到后还可以放到流中
LineNumberInputStream ----可以读取流中每行的行号(过时)

OutputStream 旗下有

FileOutputStream
PipedOutputStream
ByteArrayOutputStream
FilterOutputStream---其中他旗下有
DataOutputStream
ObjectOutputStream
BufferedOutputStream
PrintStream

流式字节序列的抽象表示,他是数据传输时的形态,而文件时数据的静态存储形式。

java的流分为节点流类和过滤流(也叫处理流),读取只能从头到尾来读

1。InputStream输入流,是用来连续读取字节的对象。。。。。输入为什么是读取???
我们这么想 InputStream To us 我们也可以把InputStream想象成一根医院里面的针管,输入当然是输入到我们身体里面,也就是读取

int read();//读取一个字节的内容,并把这个字节以整数的形式返回,如果读不到将会阻塞,如果是流的结束,那么返回-1。。。。注意:因为只读取了一个字节的数据,而一个int是四个字节,那么这个数据是放在字节的最低位上,而把其他int的高字节部分全部设置为0,这个过程与我们平常把byte转换为整数的过程是不一样的。

为什么不一样:上例子:
比如byte b =(byte)-1;的二进制w为: 1111 1111
转换成int : 的-1为 : 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111

而这个read中的-1是这样的:0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111

所以他在int中并不是表示-1 。。。。。。这样做的目的是为了区分结束符-1和传过来的-1值


int read(byte[] b);//这个方法是在一个字节都读不到的时候发生阻塞,但是他能读多少算多少,只要读到就可以返回。。。。。

int read(byte[] b ,int off,int len);//存放的地方是从b[off]开始存,然后存入长度为len

long skip(long n);//这个是包装流(或者说处理流)的方法,本来流只能顺序的读,但是包装类是脱离了底层的流的

int available();//这个是返回当前输入流中可读的字节数,这个方法可以避免程序发生阻塞哈,因为我先看看能不能读,如果有数据我再读不就行了吗,但是不停的探测时会消耗cpu资源的

void mark(int readlimit);//用于在输入流中建立一个标记,readlimit是说在建立标记的地方开始,最多还能读取多少个字节,这个方法也是包装流的

void reset();//该方法是配合mark方法使用的,使得指针回到原来的标记位置,这个也是包装流的

boolean markSupported();//是查看这个流对象是否支持mark和reset操作


2。OutputStream

void write(int b); //这个方法将一个整数中最低的字节部分写入到流中,最高字节部分被舍弃,那么为什么不用byte类型而用int类型呢。。? 因为就算用了byte类型,但是byte类型只要参与运算,那么运算的结果都会被默认为是int 类型
如果我们定义成 void wtite(byte i);
那么我们赋值需要这样
byte b = (byte)-1;
write((byte)b);//看见没,还得再转一次,我草


void wtite(byte[] b);//这个方法将b中的所有东西都输出到流当中

void write(byte[],int off,int len)

void flush();//因为应用程序和I/O设备之间有个内存缓冲区,在通常情况下只有应用程序把内存缓冲区填满以后,内存缓冲区中的内容才会被一次写入外部设备。。。但是如果你想输出的内容都输出完了还没有填满内存缓冲区怎么办呢。。。当然只能告诉计算机:哥们,我没东西可以写了,你就把缓冲区中的内容全部写到外部设备吧。。。。,注意:不是所有的outputStream都是用了这个方法,只有是用了缓冲区的OutputStream才需要使用这个方法

所以内存缓冲区有两部分的好处:
第一:提高了cpu的使用率。
第二:因为write方法还没有真正将数据写入外部设备,那么应用程序就还有机会撤销这些数据。。。
所以他提高了整个计算机的性能。。。。
坏处是:因为他没有直接写入设备,那么会降低单个应用的效率,比如在网络流中因为数据先是放在缓冲区,必然造成数据的滞后,降低数据的实时性

void close();//当使用close()方法的时候,他会自动调用flush()方法,把缓冲区的内容刷新到目标上


3. FileInputStream是用来读一个文件,那么这个文件必须存在
FileOuputStream是用来写一个文件,

创建FileOutputStream实例对象时,如果指定的文件已经存在,这个文件中的原来内容将被覆盖清除

对同一个磁盘文件创建FileInputStream对象的两种方式
1。 FileInputStream inOne = new FileInputStream("hello.test");//第一种方式只是方便而已

2. File f = new File("hello.test");
FileInputStream intwo = new FileInputStream(f);
第二种方式可以先分析文件是否存在,文件是否可写,文件是否是一个目录

FileOutputStream可以指定不存在的文件名,但是不能指定一个已经被其他程序打开了的文件,因为其他程序打开这个文件就有可能对文件进行写操作,而我们去打开就会对其他应用程序的结果造成影响

注意:Stream基于对字节进行的操作

Reader和Writer是对字符进行操作的 他们是对字符流类的抽象积累,用于简化字符串的输入输出的编程

二进制文件和文本文件的区别

二进制文件中的每个字节可以是0~255之间的任意数字,但是文本文件是由字符组成的,而并不是0~255之间的每个数字都能表示字符,所以文本文件的二进制形式是0~255之间的某些数字,不是任意数字,所以文本文件只是二进制文件的特例,为了与文本文件相区别,我们又把文本文件以外的文件称为二进制文件(狭义的)。

所以Reader和Writer主要用于读取文本文件格式的内容。。。
InputStream和OutputStream主要用于读取二进制格式的内容。。。


FileWriter out = new FileWriter("hello.txt");
out.write("www.it315.com");//注意啦,这里居然用的是字符串哈----就这个地方简化了
out.close();//即时关闭哈。。这样就可以少些out.flush();
值得注意的是,如果我们这样写:
out.write("www.it315.com".getBytes());//这是写入字节数组的write,他的内部会调用flush()方法
out.write(byte b);//如果是写入一个字节的方法是不会调用flush的

我猜:如果你仍给他一个对象,那么他是不会自动flush的,他会说哥们,太少了
如果你给他一组对象,那么他会自动刷新,他会说,哥们,来了这么多啊,我就把他们先送走把。。。

char[] buf = new char[1024];//注意啦,这里是字符数组不是字节数组
FileReader in = new FileReader('hello2.txt');
int len = in.read(buf);
String s = new String(buf,0.len);//这个Reader并没有简化编程的难度,只是把字节升级成了字符,而不是字符串,因为机器无法判断到底怎么样才算一个串。。。


包装类:

如果我们要把一个浮点小数写入文件怎么办。。?

先要将浮点小数转换成byte,再写。。

假设我们要把一个整数写入到文件中,怎么办。。。难道用FileOutputStream中的write
这个可不行,因为他只会写入整数中最低的那个位

DataOutputStream类提供了往各种输出流对象中写入各种类型的数据的方法,
你所要做的工作就是传递一个FileOutputStream输出流对象给DataOutputStream

DataOutputStream并没有对应到任何具体的流设备,一定要给他传递一个对应具体刘设别的输出对象,
完成类似功能的类就是一个包装类,也叫过滤流类或处理流类

DataOutputStream包装类的构造函数
public DataOutputStream(OutputStream out);//他不语具体的设别打交道哈

BufferedInputStream与BufferdOutputStream类

缓冲流为I/O流增加了内存缓冲区,两个基本目的是:
运行java程序依次不只写入一个字节,提高性能
由于有了缓冲区,使得在流上执行skip,mark和reset 方法都能成为可能

包装类缓冲区与底层系统提供的缓冲区的区别:
底层系统提供的缓冲区直接与目标设备交换数据,而包装类提供的缓冲区需要调用包装类所里面的输出流对象
将数据写入到目标设备或底层缓冲区中

底层缓冲区是一次在硬盘上读取大量数据和一次在硬盘上写入大量数据,而包装类缓冲区还是
一下读一个,只是缓存在包装类的内存中而已
BufferedInputStream(InputStream in); //创造一个带有32个字节的缓冲区的缓冲流
BufferedInputStream(InputStream in,int size);//按照指定大小创建缓冲区,这个大小通常应该设置成内存,磁盘扇区或者其他屋里设别的一次读写操作
所能完成的最大字节数的整数倍,比如我们的cpu一下读32bit也就是4个字节,那么size最好设置成4的整数倍

BufferedReader和BufferedWriter对字符操作---字符流

DataOutputStream提供了三个写入字符串的方法
public final void writeBytes(String s); //因为 Java是Unicode,那么每个字符占用两个字节,
这个方法就是把每个字符的低字节写入到目标设备中
public final void writeChars(String s);//这是把每个字符的两个字节都写入到目标设备中去
public final void writeUTF(String s); //写入这个字符串的UTF编码,不过是带长度头的
为什么DataInputStream类中有readUTF方法,而没有readBytes和readChars呢?
因为要在一个连续的字节流中读取一个字符串,而这个字符串只是这个连续的流中的一段内容,如果没有特别的标记作为字符串的结尾,而且事先也不知道
这个字符串的长度,那就不知道要读到什么位置啊,所以就只有一个方法了哦

通常我们可以这样哦: DataOutputStream --》BufferedOutputStream -->FileOutputSrream

我们只要关闭最顶层的数据流就可以了


PrintStream类提供了一系列的print和printLn方法,可以将数据类型的数据格式化成字符串输出

PrintStream的3个构造函数
--PrintStream(OutputStream out);
--PrintStream(OutputStream out,boolean autoflush);//这个会自动刷新缓冲区,在碰到\n
--PrintStream(OutputStream out,boolean autoflush ,String encoding);//将字符串转换成对应的字符集编码在打印
PrintWriter类是不会自动清空缓冲区,也就是他不理会\n
手动刷新缓冲区 :调用println()

注意:PrintWriter的println方法能根据操作系统的不同而生成相应的文本换行标识符。
在windows下的文本换行标识符是"\r\n"在Linux下的文本换行标识符是"\n"

ObjectInputSteam和ObjectOutputStream----这个也是包装类哈

他不会写入static和transient,因为他们本身就不是某个对象的特征嘛

下面把一个对象写入到一个文本文件当中

Student stu = new Student();
FileOutputStream fos = new FileOutputStream("Student.txt");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(stud);
os.close();


字节流与字符流的转换

能不能找到一个简单的方式来读取键盘上输入的一行字符,如何找

键盘是----System.in

InputStreamReader和OutputStreamWriter,是用于将字节流转换成字符流来读写的两个类
转换流哈

InputStreamReader的两个主要构造函数 ----字节流转字符流
InputStreamReader(InputStream in);
InputStreamReader(InputStream in,String CharserName);//第二个参数是转换的字符集

OutputStreamWriter----几乎相同

避免频繁的在字符和字节见进行转换,最好不要直接使用
InputStreamReader和OutputStreamWriter类来读写数据
用BufferedWriter类来包装OutputStreamWriter类
用 BufferedReader类包装 InputStreamReader 因为如果你读了一个字节就转换成字符,那么效率显然很低
如果包装了一层BufferedReader那么他就会度好多个字节,然后再进行转换
其实所有的字符流都是包装类


pipedInputStream的缓冲区如果写满的话,那么写进程会发生阻塞,就写不进去了,一般写进程的缓冲区是512字节

[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值