IO流学习:字节流

java的流中:以二进制读取的流主要有:
1.InputStream/OutputStream: 这是基类,它们是抽象类。
2.FileInputStream/FileOutputStream: 输入源和输出目标是文件的流。
3.ByteArrayInputStream/ByteArrayOutputStream: 输入源和输出目标是字节数组的流。
4.DataInputStream/DataOutputStream: 装饰类,按基本类型和字符串而非只是字节读写流。
5.BufferedInputStream/BufferedOutputStream: 装饰类,对输入输出流提供缓冲功能。

InputStream – 抽象类
单个字节读取:

   public abstract int read() throws IOException;

read从流中读取下一个字节,返回类型为int,但取值在0到255之间,当读到流结尾的时候,返回值为-1,如果流中没有数据,read方法会阻塞直到数据到来、流关闭、或异常出现,异常出现时,read方法抛出异常,类型为IOException,这是一个受检异常,调用者必须进行处理。read是一个抽象方法,具体子类必须实现,FileInputStream会调用本地方法,所谓本地方法,一般不是用Java写的,大多使用C语言实现,具体实现往往与虚拟机和操作系统有关。
批量读取:

public int read(byte b[]) throws IOException

读入的字节放入参数数组b中,第一个字节存入b[0],第二个存入b[1],以此类推,一次最多读入的字节个数为数组b的长度,但实际读入的个数可能小于数组长度,返回值为实际读入的字节个数。如果刚开始读取时已到流结尾,则返回-1,否则,只要数组长度大于0,该方法都会尽力至少读取一个字节,如果流中一个字节都没有,它会阻塞,异常出现时也是抛出IOException。该方法不是抽象方法,InputStream有一个默认实现,主要就是循环调用读一个字节的read方法,但子类如FileInputStream往往会提供更为高效的实现。

读入的第一个字节放入b[off],最多读取len个字节

public int read(byte b[], int off, int len) throws IOException
read(byte[] b)内部就是调用了该方法。
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);

}

流读取结束后,应该关闭,以释放相关资源,关闭方法为:

public void close() throws IOException

OutputStream --抽象类
基本方法:

public abstract void write(int b) throws IOException;

批量写入:

public void write(byte b[]) throws IOException
public void write(byte b[], int off, int len) throws IOException

在第二个方法中,第一个写入的字节是b[off],写入个数为len,最后一个是b[off+len-1],第一个方法等同于调用:write(b, 0, b.length);。OutputStream的默认实现是循环调用单字节的write方法,子类往往有更为高效的实现,FileOutpuStream会调用对应的批量写本地方法。

public void flush() throws IOException
public void close() throws IOException

flush将缓冲而未实际写的数据进行实际写入,比如,在BufferedOutputStream中,调用flush会将其缓冲区的内容写到其装饰的流中,并调用该流的flush方法。基类OutputStream没有缓冲,flush代码为空。

需要说明的是文件输出流FileOutputStream,你可能会认为,调用flush会强制确保数据保存到硬盘上,但实际上不是这样,FileOutputStream没有缓冲,没有重写flush,调用flush没有任何效果,数据只是传递给了操作系统,但操作系统什么时候保存到硬盘上,这是不一定的。要确保数据保存到了硬盘上,可以调用FileOutputStream中的特有方法。

close一般会首先调用flush,然后再释放流占用的系统资源。同InputStream一样,close一般应该放在finally语句内。

DataInputStream/DataOutputStream

void writeBoolean(boolean v) throws IOException;
void writeInt(int v) throws IOException;
void writeDouble(double v) throws IOException;
void writeUTF(String s) throws IOException;

在使用这些写入写出的方式时,需要注意写入跟写出的调用方法的顺序需要相等

output.writeInt(students.size());
        for(Student s : students){
            output.writeUTF(s.getName());
            output.writeInt(s.getAge());
            output.writeDouble(s.getScore());
        }
int size = input.readInt();
        List<Student> students = new ArrayList<Student>(size);
        for(int i=0; i<size; i++){
            Student s = new Student();
            s.setName(input.readUTF());
            s.setAge(input.readInt());
            s.setScore(input.readDouble());
            students.add(s);
        }

像这两段代码,如果写出跟写入的顺序不一样,会爆EOFException,表示意外的读取到了文件的最后,如果后面还在调用read方法但又没有数据的时候就会报错。

BufferedInputStream/BufferedOutputStream
具有缓冲功能的字节流。读取时,先从这个缓冲区读取,缓冲区读取完了后在调用安装的流读,提高性能,它的flush方法会将缓冲区的内容写到包装的流中。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值