java I/O(1)

1,在java的API中,我们可以通过输入流往程序中读入数据,也可以通过输出流把数据从程序往外写,所以有了InputStream和OutputStream两个基类,底下所有的类都是衍生出来的。
2,因为面向字节流不方便把数据保存成Unicode字符(Unicode是每个字符多个字节组成的),所有有了Reader和Writer两个基类,用来一次性能够读取两个字节,而不再是单个字节的形式了。
3,InputStream类有一个抽象方向
abstract int read()该方法读取一个字节并且返回读取的字节,如果返回-1那么就是读取到输入源的末尾,其他继承它的子类也是使用该方法时也是读取一个字节,如FileInputStream和System.in
InputStream类有方法去读取一个字节数组和跳过一些字节的方法,同样abstarct void write(int b)写入一个字节到目的地。
4,首先这两个方法是阻塞,这就意味着流是不能立刻被访问的,这种情况经常在网络通讯中可以见到。
4,available方法可以让你检查你检查你当前可读的数据大小,如:
int bytesAvailable = in.available();
if(bytesAvailable > 0){
    byte[] data = new byte[bytesAvailable];
    in.read(data);
}
5,当你完成了读写操作后,应该调用close()方法把数据流关闭,这个方法会释放被占用的系统资源,如果你打开了很多个流操作但是没有去关闭它们,你的系统资源可能会被耗尽。注意,比如你在关闭一个输出流时要记得去flushes一下缓冲区,因为你的数据有可能暂放在缓冲区内,你要确保你的数据能够全部写入到硬盘。你可以调用flush方法。
6,InputStream和OuputStream底下有很多的子类,它的子类能够让你更好的读取数据,比如DataInputStream和DataOutputStream这两个类能够让你读取和写入原始java的二进制数据类型,可以让你方便的读取不同的数据类型。还有ZipInputStream和ZipOutputStream能够以Zip的二进制数据类型来进行读取和写入文件(the ZipInputStream and ZipOutputStream that let you read and write files in the familiar
ZIP compression format.
)。

Reader和Writer类
同样这两个类也具有跟InputStream和OutputStream这两个类同样的方法
abstract int read()
abstarct void write(int c)
不同的是这里的read方法返回了任何一个Unicode的代码单元。(从0到65535之间),同样返回-1表示读取到文件末尾。同样没忘了flush和close方法。

有一点需要强调的是Closeable,Flushable,Readable,Appendable接口,看看这四个接口是干嘛用的。
Closeable接口:void() 关闭此流并释放与此流关联的所有系统资源。
Readable接口:read(CharBuffer cb)试图将字符读入到字符缓冲区。
Flushable接口:flush()通过将所有已缓冲输出写入底层流来刷新此流
Appendable接口:有两个方法可以在当前的字符后面继续append字符,常见两个方法
Appendable append(char c)
Appendable append(CharSequence s)
java.lang.CharSequence 1.4
char charAt(int index)
returns the code unit at the given index.
int length()
returns the number of code units in this sequence.
CharSequence subSequence(int startIndex, int
endIndex)
returns a CharSequence consisting of the code units
stored at index startIndex to endIndex - 1.
String toString()
returns a string consisting of the code units of this
sequence.

CharSequence类的存在其实是为了CharBuffer, Segment, String, StringBuffer, StringBuilder提供了统一的只读的接口,这几个类除了Segment外,基本都是继承了Appendable和CharSequence接口。

FileInputStream和FileOutputStream类直接把输入输出流接到磁盘文件上,也就是说你可以直接对文件设置进行读写操作。
FileInputStream fin = new FileInputStream("your file path")
System.getProperty("user.dir")这个方法可以直接获取你的文件路径信息

这里遇到了一个问题:But just as the FileInputStream has no methods to read numeric types, the DataInputStream has no method to get data from a file.那么怎么才能从文件流中读出数据类型出来呢?
java采用了一个层叠的模式,也就是一层包着一层,
FileInputStream fin = new FileInputStream("employee.dat");
DataInputStream din = new DataInputStream(fin);
double s = din.readDouble();
为什么用这样的方式就可以实现读取数据类型呢?不妨可以打开源码看一下,
public
class DataInputStream extends FilterInputStream implements DataInput {

    /**
     * Creates a DataInputStream that uses the specified
     * underlying InputStream.
     *
     * @param  in   the specified input stream
     */
    public DataInputStream(InputStream in) {
    super(in);
    }
    ...........
    }
首先可以看到当我们实例化FileInputStream时会把它传入到DataInputStream中的成员变量InputStream,当调用DataInputStram的构造方法时会去实例化super(in).从继承来看super就是FilterInputStream,这个类的作用就是从流中读取字节出来。那么看看源码中的实现:
public
class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in;

    /**
     * Creates a <code>FilterInputStream</code>
     * by assigning the  argument <code>in</code>
     * to the field <code>this.in</code> so as
     * to remember it for later use.
     *
     * @param   in   the underlying input stream, or <code>null</code> if
     *          this instance is to be created without an underlying stream.
     */
    protected FilterInputStream(InputStream in) {
    this.in = in;
    }
    }

可以看到FileInputStream的实例会被传到FilterInputStream中来,那么InputStream in = new FilterInputStream("path"),根据多态的思想,那么FilterInputStream类中调用的in.read等等的方法实际上调用的是FileInputStream的方法,而DataInputStream类继承FilterInputStream类,那么DataInputStream享有FilterInputStream类中的InputStream in实例。那么DataInputStream中的readData()方法做的是就是先去调用FileInputStream类中的read方向先去获得字节数据,然后再通过readData方法中具体的算法去获得具体的数据类型。其实这里很像代理的模式!

先到这里先。。。。继续深入学习



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值