字节流-InputStream 和 OutputStream
上篇文章我们讲了字符流的基本操作,并且通过阅读源码我们知道,字符流就是基于字节流做的实现——一次读取两个字节组成一个字符。
InputStream
此抽象类是表示字节输入流的所有类的超类。
需要定义 InputStream 子类的应用程序必须总是提供返回下一个输入字节的方法。
OutputStream
此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。
需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法。
FileInputStream 和 FileOutputStream
还是以之前那个文件读写的 demo 为例,我们先看一下字节流怎么玩的~
try {
// 创建读取流和写入流
FileInputStream fis = new FileInputStream("raw.txt");
FileOutputStream fos = new FileOutputStream("target.txt");
// 读取单个字符,自动往下读
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
使用 I/O 复制图片
这个操作和上面的代码一样,注意图片是二进制数据,只能使用字节流读取,不能使用字符流哦。
字节流缓冲区
这个和字符流缓冲区基本没差了,直接贴代码吧~
try {
// 创建读取流和写入流
FileInputStream fis = new FileInputStream("raw.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("target.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 读取单个字符,自动往下读
byte[] buf = new byte[1024];
int len;
while ((len = bis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
字节流拷贝video 等大文件
- 除文本文件之外必须使用字节流
- 文件比较大的必须使用缓冲区提升效率
代码就补贴了,同上。
自定义字节流缓冲区
这个和自定义字符流缓冲区一样,实现思想就不再赘述了,不记得的同学请翻上一篇笔记。
直接贴代码吧,没什么特别的。
class MyBufferedImputStream {
private InputStream in;
private byte[] buf = new byte[1024 * 8];
private int pos = 0;
private int count = 0;
public MyBufferedImputStream(InputStream in) {
this.in = in;
}
// 从缓冲区一次读一个字节
public int read() throws IOException {
// 通过in对象读取硬盘上的数据,存储在buf
if (count == 0) {
count = in.read(buf);
if (count < 0)
return -1;
byte b = buf[pos];
count--;
pos++;
return b;
} else if (count > 0) {
byte b = buf[pos];
pos++;
count--;
return b;
}
return -1;
}
//关闭流
public void myClose() throws IOException {
in.close();
}
}
读取键盘录入
这个好像超纲了,Android 并不需要读取键盘录入。至于 EditText 是怎么读取键盘录入的,我们以后学习 EditText 源码的时候再慢慢研究。
Java 里面读取键盘录入主要用的是InputStream in = System.in;,有需要的小伙伴自行研究吧。
转换流 InputStreamReader 和 OutputStreamWriter
java中需要转换流就会使用到转换流,使用到了 InputStreamReader/OutputStreamWriter。
我们前面也说了 FileReader 继承自InputStreamReader,内部构造方法 new FileInputStream(),因此,我们知道字符流就是字节流使用了转换流。
还是写一下代码吧,顺便讲一下上面提到的键盘录入
//获取键盘录入对象
InputStream in = System.in;
//转换
InputStreamReader isr = new InputStreamReader(in);
//提高效率
BufferedReader bur = new BufferedReader(isr);
String line;
try {
while ((line = bur.readLine()) != null) {
if (line.equals("over"))
break;
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
没什么意思,写入转换流也是一样的操作,我就不写了。
流操作的规律
- 读取大文件记得用字*流缓冲去提高效率
- 读取文本文件优先使用字符流、其余一概用字节流
- 文件读写操作一般都是使用 FileInput(Output)Stream。