字节流
字节流
字节流的输入输出都是以字节为单位处理数据,一个字节等于 8 个二进制位,即由 8 位 0 或 1 组成的序列,如 01102300 为一个字节。在Java中所有的字节流都是从抽象类InputStream或OutputStream 类继承而来。大部分字节流使用方式相同,只是它们的构造方式可能不一样。
InputStream
InputStream提供的方法
方法名 | 签名 | 描述 |
---|---|---|
read | public abstract int read() | 这是一个抽象方法,需要子类实现,用于从输入流中读取下一个字节数据。由于一个字节是 8 位,返回值介于0~255之间,如果没有可读数据,即达到了流的末尾,则返回-1。方法会一直阻塞直到有字节数据可读、到达流末尾或者发生IO异常。 |
read | public int read(byte b[]) | 从输入流中读取b.length个字节,并储存到字节数组b中,如果b⻓度为 0 ,则不会读取任何字节数据,方法返回 0 。 read(byte b[]) -> read(byte b[], int off, int len) -> read |
read | public int read(byte b[], int off, int len) | 从输入流中读取最多len个字节,如果len为 0 ,不会读取任何字节数据,直接返回 0 ,读取的字节从数组b的off位置开始存放。 read(byte b[], int off, int len) -> read() |
skip | public long skip(long n) | 跳过并丢弃输入流中的n个字节数据,通过调用read(byte b[], int off, int len)读取字节并丢弃。 |
available | public int available() | 返回下一次操作时,输入流中预估的可读字节数量 |
close | public void close() | 关闭输入流,释放与流关联的系统资源 |
markSupported | public boolean markSupported() | 用于测试输入流是否支持mark与reset方法 |
mark | public synchronized void mark(int readlimit) | 在输入流中标记当前位置,标记位置后,还可以读取最多readlimit字节,后续可以通过reset方法回到上一次mark的位置,达到重复读取相同字节数据的操作,使用mark方法,则markSupported必须返回true,在关闭的流中调用mark方法,不会有任何效果。 |
reset | public synchronized void reset() | 在流中复位,回到上一次调用mark方法标记的位置,如果未发现任何mark或者上一次mark标记后读取的字节数超过readlimit,则发生IOException,使用reset方法,则markSupported必须返回true。 |
InputStream中的方法大部分都是一种规范,最终的字节流子类某些方法可能会有所不同。
OutputStream
OutputStream提供的方法
方法名 | 签名 | 描述 |
---|---|---|
write | public abstract void write(int b) | 这是一个抽象方法,需要子类实现,用于将指定的字节数据写入到输出流中,在Java中int是 32 位,4个字节,write方法实际写入的只是整型数据b的低 8位,其余 24 位直接忽略。write public void write(byte b[]) 将字节数组b中的数据写入到输出流中,write(byte b[])->write(byte b[], int off, int len)->write() |
write | public void write(byte b[], int off, int len) | 从字节数组b下标为off的位置开始,将len个字节数据写入到输出流中。write(byte b[], int off, int len)->write() |
flush | public void flush() | 刷新输出流,强制一些缓冲输出流将内部缓冲的一些字节数据立即写入目标地,如果目标地是磁盘文件,调用flush方法后,并不保证文件⻢上更新,这取决于操作系统。 |
close | public void close() | 关闭输出流,释放与流关联的系统资源 |
操作使用
文件IO字节流FileInputStream、FileOutputStream是使用最广泛的两个类,以这两个类进行操作说明。
public class CopyBytes { |
IO流操作完成后,一定要在finally语句块中进行关闭,Java7开始提供了try-with-resources语法,编
译器识别该语法后,在字节码文件中自动生成了对应的finally语句块,并在语句块中关闭对应的流。
try (...) { |
用try-with-resources语法读写文件代码
public class CopyBytes2 { |
如source.txt文件有如下字符内容:I2023,我 ,文件编码为UTF-8时输出 9 个字节(汉字占用了三个字节)。
最后三个大于 127 的十进制值则表示汉字 我,其余的对应的是ascii字符。
FileOutputStream可以控制字节内容写入起始位置
- 通过new FileOutputStream(D://test/target.txt) 构造输出流
每次从文件开头写入字节数据,因此会覆盖上一次打开文件时写入的内容。
public class FileOutputStreamDemo { |
- 通过new FileOutputStream(D://test/target.txt, true) 构造输出流
每次从文件末尾写入字节数据,相当于向文档中追加数据内容,多次运行上述main方法,会发现
D://test/target.txt文件内容增加。
字节流是IO流中最底层的低水平操作流,文件中包含的是字符数据,更高效的方法是通过字符流进行操作。
评论