CoreJava学习心得13

1Java中的I/O

使用I/O流访问file中的内容。
JVM与外界通过数据通道进行数据交换。
分类:按流分为输入流和输出流,按传输单位分为字节流和字符流,还可以分为节点流和过滤流。

节点流:负责数据源和程序之间建立连接。
过滤流:用于给节点增加功能。在关闭流时如果使用了过滤流,只需关闭最外层的流就可以了。

过滤流的构造方式是以其他流为参数构造(这样的设计模式称为装饰模式)并且过滤流本身不能使用,他的作用只是增强节点流的功能。

字节输入流:

InputStream类 (抽象类)
所有字节输入流的父类

io包中的InputStream为所有字节输入流的父类。
int read();读入一个字节(每次一个);
可先使用new byte[],调用read(byte[] b),byte[]数组长度决定了可以读取到的最大字节数,用来调整效率。read (byte[])返回值可以表示有效数;read (byte[])返回值为-1表示结束。

字节输出流:io包中的OutputStream位所有字节输入流的父类。Write和输入流中的read相对应。

在流中close()方法由程序员控制。因为输入输出流已经超越了VM的边界,所以有时可能无法回收资源。
原则:凡是跨出虚拟机边界的资源都要求程序员自己关闭,不要指望垃圾回收。
以Stream结尾的类都是字节流。
如果构造FileOutputStream的同时磁盘会建立一个文件。如果创建的文件与磁盘上已有的文件名重名,就会发生覆盖。
用FileOutputStream中的boolean,则视添加情况,将数据覆盖重名文件还是将输入内容放在文件的后面。(编写程序验证)


如:FileInputStream,ObjectInputStream,PipedInputStrean都是InputStream类的子类。

1) 三个基本的read()方法
a. int read(): 从流里读出的一个字节或者-1; (实际读了多长)
b. int read(byte[]):将数据读入到字节数组中,并返回所读的字节数; (期望读了多长)
c. int read(byte[], int , int):两个int参数指定了所要填入的数组的子范围。
2) 其它方法
a. void close(): 关闭流,如使用过滤器流,关闭最外部的流,会关闭其余的流。
b. int available(): 返回可从流中读取的字节数。
c. void skip(long): 丢弃了流中指定数目的字符。
d. boolean markSupported()
e. void mark(int)
f. void rese()

OutputStream类(抽象类)
所有输出流的父类。

1) 三个基本的write()方法
a. void write()
b. void write(byte[])
c. void write(byte[], int , int)
2) 其它方法
a. void close(): 关闭流,如使用过滤器流,关闭最外部的流,会关闭其余的流。
b. void flush(): 允许你强制执行写操作。
注意:在流中close()方法由程序员控制。因为输入输出流已经超越了JVM的边界,所以有时可能无法回收资源。
原则:凡是跨出虚拟机边界的资源都要求程序员自己关闭,不要指望垃圾回收。

基本输入输出所使用的类的介绍:

FileInputStream和FileOutputStream (文件输入输出流)

以上两个是字节流
1) 结点流,可以对磁盘文件进行操作。
2) 要构造一个FileInputStream, 所关联的文件必须存在而且是可读的。
3) 要构造一个FileOutputStream而输出文件已经存在,则它将被覆盖。

FileInputStream infile = new FileInputStream("myfile.dat");
FIleOutputStream outfile = new FileOutputStream("results.dat");
FileOutputStream outfile = new FileOutputStream(“results.dat”,true);
参数为true时输出为添加,为false时为覆盖。

FileOutputStream类代码:(为什么能建文件)
Public FileOutputStream(String name){
This(name!=null?new File(String):null,false);
}



DataInputStream和DataOutputStream(字节流)

以上两个是过滤流。通过流来读写Java基本类,注意DataInputStream和DataOutputStream的方法是成对的。 支持直接输出输入各种数据类型。
writeBoolean(boolean b),readBoolean() ------以1bit数据传送
writeByte(int),readInt()------以1 byte数据传送
writeBytes(String s),readLine() (已过时方法)将字符串按字节顺序写出到基础输出流中以byte序列数据传送
writeChar(int v),readChar()――――――以 2 byte
writeChars(String s),readChar()-------------以 2 byte序列
writeDouble(double d),readDouble() -------以 8 byte
writeInt(int v),readInt()
writeLong(long l),readLong()
writeShort(short s),readShort()
writeUTF(String),readUTF()-----------能输出中文!

注意:使用DataOutputStream/DataInputStream时,要注意写入顺序和读取顺序相同,否则会将没有分割写入的信息分割不正确而读取出错误的数据。


BufferInputStream和BufferOutputStream(带缓存的字节流)

以上两个是过滤流,可以提高I/O操作的效率 ,用于给节点流增加一个缓冲的功能。

在JVM的内部建立一个缓冲区,数据先写入缓冲区,等到缓冲区的数据满了之后再一次性写出,效率很高。使用带缓冲区的输入输出流的速度会大幅提高,缓冲区越大,效率越高。(这是典型的牺牲空间换时间)

切记:使用带缓冲区的流,如果数据数据输入完毕,使用flush()方法将缓冲区中的内容一次性写入到外部数据源。用close()也可以达到相同的效果,因为每次close()都会调用flush()。一定要注意关闭外部的过滤流。

管道流(和UnixC++中的FIFO相同)
PipedInputStream和PipedOutputStream (字节流)

这两个是节点流,注意,用来在线程间通信。

 PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream();
try
{
pos.connect(pis);
new Producer(pos).start();//线程类对象,在构造时,使用管道流通信
new Consumer(pis).start();//线程类对象,在构造时,使用管道流通信
}
catch(Exception e)
{
e.printStackTrace();
}


随机存取文件

RondomAccessFile类允许随机访问文件,这个类也是支持直接输出输入各种数据类型。
getFilepoint()可以知道文件中的指针位置,使用seek()定位。
Mode(“r”:随机读;”w”:随机写;”rw”:随机读写)
1) 实现了二个接口:DataInput和DataOutput;
2) 只要文件能打开就能读写;
3) 通过文件指针能读写文件指定位置;
4) 可以访问在DataInputStream和DataOutputStream中所有的read()和write()操作;
5) 在文件中移动方法:
a. long getFilePointer(): 返回文件指针的当前位置。
b. void seek(long pos): 设置文件指针到给定的绝对位置。
c. long length(): 返回文件的长度。


字符流

字符流可以解决编程中字符的编码问题。从字符到整数,对字符集和整数集建立一一对应的关系,就算叫做编码,从整数映射到字符,就叫做解码。

编码问题:

字节流的字符编码:
字符编码把字符转换成数字存储到计算机中,按ASCii将字母映射为整数。
把数字从计算机转换成相应的字符的过程称为解码。

编码的方式:
每个字符对应一个整数。不同的国家有不同的编码,当编码方式和解码方式不统一时,产生乱码。因为美国最早发展软件,所以每种的编码都向上兼容ASCII 所以英文没有乱码。

ASCII(数字、英文)1个字符占一个字节(所有的编码集都兼容ASCII)
ISO8859-1(欧洲) 1个字符占一个字节
GB-2312/GBK 1个字符占两个字节
Unicode 1个字符占两个字节(网络传输速度慢)
UTF-8 变长字节,对于英文一个字节,对于汉字两个或三个字节。


InputStreamReader和OutputStreamWriter(字节流转化成字符流的桥转换器)
这两个类不是用于直接输入输出的,他是将字节流转换成字符流的桥转换器,并可以指定编解码方式。

Reader和Writer (字符流类,所有字符流的父类型)

1) Java技术使用Unicode来表示字符串和字符,而且提供16位版本的流,以便用类似的方法处理字符。
2) InputStreamReader和OutputStreamWriter作为字节流与字符流中的接口。
3) 如果构造了一个连接到流的Reader和Writer,转换规则会在使用缺省平台所定义的字节编码和Unicode之间切换。

BufferedReader/(BufferedWriter,不常用)(这两个类需要桥转换)
PrintWriter(带缓存的字符输出流,不需要桥转换)

常用输入输出类型,不需要桥接,其中其它方法请参看API文档。
以上两个都是过滤流,需要用其他的节点流来作参数构造对象。
BufferedReader的方法:String readLine(),当他的返回值是null时,就表示读取完毕了。要注意,再写入时要注意写换行符,否则会出现阻塞。
BufferedWriter的方法:newLine() ,这个方法会写出一个换行符。
PrintWriter的方法:println(….String,Object等等)和write(),println(...)这个方法就不必再写换行符了,在使用时会自动换行。

注意:在使用带有缓冲区的流时,在输入之后就要flush()方法,把缓冲区数据发出去。

原则:保证编解码方式的统一,才能不至于出现错误。
java.io包的InputStreamread输入流的从字节流到字符流的桥转换类。这个类可以设定字符转换方式。
OutputStreamred:输出流的字节流桥转换成字符流
Bufferread有readline()使得字符输入更加方便。
在I/O流中,所有输入方法都是阻塞方法。
Bufferwrite给输出字符加缓冲,因为它的方法很少,所以使用父类PrintWrite,它可以使用字节流对象,而且方法很多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值