InputStream字节输入流
常用子类
- FileInputStream 文件字节输入流
- BufferedInputStream 缓冲字节输入流
- ObjectInputStream 对象字节输入流
关系图
FileInputStream
- FileInputStream类中的方法
用法 | 解释 |
---|---|
int available() | 返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。 |
void close() | 关闭此文件输入流并释放与流相关联的任何系统资源。 |
protected void finalize() | 确保当这个文件输入流的 close方法没有更多的引用时被调用。 |
FileChannel getChannel() | 返回与此文件输入流相关联的唯一的FileChannel对象。 |
FileDescriptor getFD() | 返回表示与此 FileInputStream正在使用的文件系统中实际文件的连接的 FileDescriptor对象。 |
int read() | 从该输入流读取一个字节的数据。 |
int read(byte[] b) | 从该输入流读取最多 b.length个字节的数据为字节数组。 |
int read(byte[] b, int off, int len) | 从该输入流读取最多 len字节的数据为字节数组。 |
long skip(long n) | 跳过并从输入流中丢弃 n字节的数据。 |
- FileInputStream用法详解
FileInputStream调用read()方法详解
主要问题:
- news1.txt文档中写了zhangsan123
因为我们调用的read方法是一个字节一个字节的读取,如果输入汉字,汉字是在utf-8中由三个字节组成- FileInputStream fileInputStream = new FileInputStream(filePath);这样直接写会报出FileNotFoundException异常,我们捕获一下
- 我们查看jdk帮助文档,发现read()方法的特点
- 从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
- 数据的下一个字节,如果达到文件的末尾, -1 。
- //这里read方法也会报出异常,所以我们将catch的异常范围扩大到IOException
- 们这里输出readData,但是readData为int类型,我们在文件中有String类型的数据,所以将int转换为char
- 使用完之后,需要关闭文件流,释放资源
- 重点问题:这里的fileInputStream对象是在try中创建的,FileInputStream fileInputStream = new FileInputStream(filePath);
作用域只在try{}中,所以我们将fileInputStream定义到try的外面
问题2:这里的close又报出IO异常,所以我们将异常捕获一下
捕获之后就关闭了,不要再在finally里套娃捕获close的IO异常
@Test
public void Test(){
//news1.txt文档中写了zhangsan123
//因为我们调用的read方法是一个字节一个字节的读取,如果输入汉字,汉字是在utf-8中由三个字节组成
//所以只能读取每个汉字的一个字节,最后肯定会乱码
String filePath="D:/IOFile/news1.txt";
int readData=0;
FileInputStream fileInputStream =null;
//FileInputStream fileInputStream = new FileInputStream(filePath);这样直接写会报出FileNotFoundException异常,我们捕获一下
try {
//在写finally之前写的FileInputStream fileInputStream = new FileInputStream(filePath);
fileInputStream = new FileInputStream(filePath);
//这里我们想要读取文件中的数据就需要调用FileInputStream中的read方法
//我们查看jdk帮助文档,发现read()方法的特点
//从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
//数据的下一个字节,如果达到文件的末尾, -1 。
//这里read方法也会报出异常,所以我们将catch的异常范围扩大到IOException
while ((readData=fileInputStream.read())!=-1){
//read方法读到了-1说明文件到了末尾
//我们这里输出readData,但是readData为int类型,我们在文件中有String类型的数据,所以将int转换为char
System.out.print((char) readData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//使用完之后,需要关闭文件流,释放资源
//重点问题:这里的fileInputStream对象是在try中创建的,FileInputStream fileInputStream = new FileInputStream(filePath);
//作用域只在try{}中,所以我们将fileInputStream定义到try的外面
//问题2:这里的close又报出IO异常,所以我们将异常捕获一下
//捕获之后就关闭了,不要再在finally里套娃捕获close的IO异常
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream调用read(byte[] b)方法详解
@Test
public void Test2(){
String filePath="D:/IOFile/news1.txt";
int readNum=0;
//创建一个大小为8的byte类型的数组,每次读取8个字节
//读取zhangsan123,先读取zhangsan,在读取123
byte[] bytes=new byte[8];
FileInputStream fileInputStream =null;
try {
fileInputStream = new FileInputStream(filePath);
//read(byte[] b)方法读到了-1说明文件到了末尾
//read(byte[] b)方法读取正常,返回实际读取的字节数
// new String(b, n, m)的用法,其中b为byte[]数组,n,m为int类型,
// 下标为n开始前进m个下标的那一段数组变为字符串
while ((readNum=fileInputStream.read(bytes))!=-1){
System.out.print(new String(bytes,0,readNum));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
debug测试readNum数值的变化,如何以大小为8的byte类型的数组读取11个字节的数据
这里byte类型的数组中只是最后三个字节(123)代替了bytes数组中前三个字节,并不是把整个数组的数据删除完全在将123添加进数组中,但是并没有什么影响,因为我的new String只输出下标0开始往前readNum的数据,此时因为read方法,readNum从8变成了3,所以刚刚好输出前3个数据