概述

  基本流有字节输入输出流(InputStream,OutputStream),和字符输入输出流(Reader,Writer),它们都是抽象类,作为Java IO API中其他所有流的父类存在.

  我们知道数据存储在介质中时是以二进制的形式存在,用字节(byte)形式就可以实现读写,在jdk1.0版本中也只有字节输入输出流(InpuStream,OutputStream),在之后的1.1版本才加入了字符输入输出流(Reader,Writer),这是为了满足一些文本读写方便,比如中文字符可能占有两到三个字节,这时如果使用字节流,则不便使用,可能造成乱码,而字符流则可以根据字符编码一次读写一个字符.

  在开始学习这四种基本流时,将列出它所有的成员方法,一一说明,基本流的成员方法比较少,而且他的各种功能的子类都是通过重写这些方法来实现不同功能,在后面学习具体类时将不再这样列举

InputStream

  InputStream是java IO所有字节输入流的超类,如果你自己想要实现一个字节输入流组件,最好直接继承InputStream而不是他的子类,这样你可以处理所有类型的输入流.从上图中我们可以看到InputStream实现了Closeable接口,实际四个基本流都实现了此接口,其接口close()方法作为流操作结束时释放系统资源用.下面我们着重看InputStream的成员方法.

public abstract int read() throws IOException;

read()是一个抽象方法,由子类重写具体实现方式,它用来读取数据,且每次只读取一个字节,并以int类型返回该字节,当InputStream读取到文件末尾,再也没有数据时,则返回-1;

public int read(byte b[]) throws IOException{...}

  read(byte[])方法一次读取多个字节,并将其储存在传入的byte数组中,相比read(),其速度提高了很多.read(byte[])返回的是int类型所读取字节数,和read()一样,到文件末尾时,返回-1.

public int read(byte[] b,int off,int len) throws IOException{...}

  read(byte[],int,int)  read(byte[])类似,不同的是read(byte[] b ,int off,int len)可以通过传入参数off选择开始要写入到的数组索引位置,以及len确定要读取的字节数,具体细节可以看源码

public int read(byte b[], int off, int len) throws IOException {
if (b == null) { //确保传入要存储数据的数组不为空,否则抛出空指针异常
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) { //这里要判断传入的参数是否正常 其中 len > b.length - off是为了检查写入的字节数会不会超出数组索引
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
} int c = read();
if (c == -1) { //判断读取文件是否为空
return -1;
}
b[off] = (byte)c; //将读入的第一个字节放入选择的数组索引off处 int i = 1; //变量i用来计实际读入数组的字节数
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}

public long skip(long n) throws IOException{...}

  skip(long)用来跳过不读一些字节数,InputStream定义了一个MAX_SKIP_BUFFER_SIZE常量,大小为2048,这是一次所能跳过的最大字节数,其返回值为long类型的实际跳过字节数;

public int available() throws IOException{...}

  available()用来获取流中可读取数据大小,InputStream中此方法默认返回0,由其子类重写来实现具体方法;

public void close() throws IOException{}

  close()方法用来读取结束后,关闭流,释放系统资源,此方法一定要确保执行,否则会大量系统资源被占用得不到释放,会导致内存溢出.

public boolean markSupported(){}

  markSupported()是一个标记方法,用来表示是否支持mark(int)和reset()方法,InputStream 默认返回false,如果要想支持mark(int)和reset()方法,应当重写markSupport()使其返回true.

public synchronized void mark(int readlimt) {}

  mark(int)方法用来标记一个读取的文件字节位置,当执行reset()方法时,InputStream可以重新从此处读取,这适用于一些分析器,这些分析器有时需要预读后面一部分字节,如果没有发现目标,则返回重写读取.

public synchronized void reset() throws IOException{}

  reset()方法将流读取重置为mark(int)方法标记的位置

OutputStream

  OutputStream是java IO所有字节输出流的超类,它实现了两个接口,Closeable和Flushable,其中Flushable接口的flush()方法是将缓冲区的数据直接刷入到输入流所要写入的对象,具体将在讲缓冲流的时候分析.下面我们看OutputStream的成员方法;

  public abstract void write(int b) throws IOException;
    write(int)方法用来写入一个字节的数据,但方法里传入的是一个int类型数据,不过这里只会写入int类型数据第一个字节,后面三个字节将被抛弃,也就是写入低8位,忽略高24位
  public void write(byte b[]) throws IOException
    write(byte[])方法是将一个数组的数据写入到字节输出流中,
  public void write(byte b[], int off, int len) throws IOException
    和write(byte[])一样的用法,不同的是这里可以从数组指定索引处开始写入,并且可以设定要写入的字节长度,细节可以查看源码
    public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}

  public void flush() throws IOException {}
     在使用缓冲流时,写入到流的数据并不会立即写入磁盘中,而是存在一个缓冲区,等到缓冲区满后才会执行实际写入,如果调用flush()方法,则立即执行将缓冲区数据写入到文件,flush()方法在OutputStream中方法体为空,需要子类重写去实现.     public void close() throws IOException {}      
     同InputStream Reader


Reader是java io中所有字符输入流的超类,它的大部分方法和InputStream相同,只不过Reader是以字符的形式读取数据,所以在一些需要人们阅读的文件读取上使用Reader.Reader相比InputStream多实现了一个Readerable接口,它使Reader可以将读取的数据存储在一个缓冲区内.而且Reader有两个构造方法,可以使用自己或者传入的对象作为同步锁,以保持读取同步,下面和InputStream相同的方法不再列举,可以自己参考InputStream.

public int read(java.nio.CharBuffer target) throws IOException {...}
public int read() throws IOException {...}

  一次读取一个字符,并将该字符以int类型返回,当读到文件尾没有数据时,返回-1
public int read(char cbuf[]) throws IOException {...}

  一次读取多个字符,并将字符放到传入的字符数组中,返回值为实际读取的字符数,到文件尾没有数据时返回-1
abstract public int read(char cbuf[], int off, int len) throws IOException;

  一次读取多个字符,并将字符放入传入的字符数组中,并且可以指定传入字符数组索引和传入的字符数,返回值同样为实际读取字符数,到文件尾没有数据时返回-1

public boolean ready() throws IOException {...}

  ready()告诉程序字符流是否可以被读取,Reader中默认返回false

Writer

Writer是java IO中所有字符输出流的超类,它的大部分方法和OutputStream一样,不同的是Writer写入的是字符.同Reader一样Writer有两个构造方法,可以使用自己或者传入的对象作为同步锁,以保证写入同步,,此外Writer还实现了一个Appenderable接口,可以追加写入字符

 

java I/O框架 (三)基本流的更多相关文章

  1. java I/O框架 (四)文件流

    文件读取 FileInputStream FileReader 文件写入 FileOutputStream FileWriter 随机文件读写 RandomAccessFile 一.文件读取 File ...

  2. Java函数式编程:三、流与函数式编程

    本文是Java函数式编程的最后一篇,承接上文: Java函数式编程:一.函数式接口,lambda表达式和方法引用 Java函数式编程:二.高阶函数,闭包,函数组合以及柯里化 前面都是概念和铺垫,主要讲 ...

  3. JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码

    JAVA之旅(三十)--打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 三十篇了,又是一个 ...

  4. 从零开始实现一个简易的Java MVC框架(三)--实现IOC

    Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency ...

  5. 《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)

    1.简介 上一篇介绍了POM的基础理论知识和非POM方式写脚本,这篇介绍利用页面工厂类(page factory)去实现POM,通过查看PageFactory类,我们可以知道它是一个初始化一个页面实例 ...

  6. 专题笔记--Java 类集框架

    Java 类集框架 1. Java类集框架产生的原因 在基础的应用中,我们可以通过数组来保存一组对象或者基本数据,但数组的大小是不可更改的,因此出于灵活性的考虑和对空间价值的担忧,我们可以使用链表来实 ...

  7. [翻译]现代java开发指南 第三部分

    现代java开发指南 第三部分 第三部分:Web开发 第一部分,第二部分,第三部分 =========================== 欢迎来到现代 Java 开发指南第三部分.在第一部分中,我们 ...

  8. JAVA之旅(三十五)——完结篇,终于把JAVA写完了,真感概呐!

    JAVA之旅(三十五)--完结篇,终于把JAVA写完了,真感概呐! 这篇博文只是用来水经验的,写这个系列是因为我自己的java本身也不是特别好,所以重温了一下,但是手比较痒于是就写出了这三十多篇博客了 ...

  9. Java异步NIO框架Netty实现高性能高并发

    原文地址:http://blog.csdn.net/opengl_es/article/details/40979371?utm_source=tuicool&utm_medium=refer ...

随机推荐

  1. PHP与XML

    代码: <?php $dom= new DomDocument('1.0'); $books=$dom->appendChild($dom->createElement_x_x('b ...

  2. win10汇编如何debug(小白向)

    先引用别人的方法 http://blog.csdn.net/lcr_happy/article/details/52491107 按他所说的下完对应软件后,安装其中的dosbox,然后将debug.e ...

  3. 最全 Linux 磁盘管理基础知识全汇总

    一.存储设备的挂载和卸载 存储设备的挂载和卸载常用操作命令:fdisk  -l.df.du.mount.umount. fdisk  -l 命令 1.作用 查看所有硬盘的分区信息,包括没有挂上的分区和 ...

  4. Hadoop-2.6.5安装

    简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个分布式文 ...

  5. QQ浏览器等window.innerHeight首次读取的高度不正确的解决办法

    问题描述 移动端的页面,需要处理首屏为一满屏.并且,采用javascript计算高度来设置容器高度的方案. <!DOCTYPE html> <html> <head> ...

  6. 洛谷 [P1963] [NOI2009] 变换序列

    这是一道二分图匹配的题 先%dalao博客 建图并没有什么难的,但是关键在于如何使字典序最小. 一个很显然的想法是先求出一个完美匹配,然后从x集合的第一个元素开始,如果该元素匹配的较小的一个,那么继续 ...

  7. 前端系列之CSS基础知识概述

    1.什么是DIV (1).div就是html一个普通标签,进行区域划分.特性:独自占一行.独自不能实现复杂效果.必须结合css样式进行渲染. (2).div通常其是块级元素 (3).div是定义文档中 ...

  8. nginx隐藏版本号

    在实际运用nginx中我们最好将我们的版本号直接隐藏,因为有些版本号的nginx被爆出了漏洞,所以我们为了安全起见,最好将我们的版本号隐藏. 1.对于未安装的nginx我们使用源码编译安装才可以将版本 ...

  9. 游戏2048源代码 - C语言控制台界面版

    一.游戏介绍 <2048>是最近比较流行的一款数字游戏.原版2048首先在github上发布,原作者是Gabriele Cirulli.它是基于<1024>和<小3传奇& ...

  10. 面向对象编程总结--Python

    万物皆为对象.自然环境赋予人类无尽的遐想,而面向对象编程之思想就是来自于大自然.自然界,类和对象比比皆是,比如:鸟类和麻雀,鱼和鲤鱼......其中鸟类就是各种鸟的总称,而麻雀只不过是其中之一(对象) ...