字节流基类包括 inputStream 和 outputStream 两个基类。
一、inputStream 的使用;
inputStream是抽象基类,不能直接拿过来使用,必须使用它的具体实现类,比如FileInputStream、byteArrayStream等。
InputStream中的主要方法:
阻塞方法: read( ),
int read():读取单个字节,返回此字节
int read( byte [] b) // 批量读取字节到byte数组中去,返回读取的有效字节个数
int read( byte [ ] b , int off , int len ) ; 批量读取字节存到指定数组中,从数组b偏移 off个单位后开始存放,len表示存入数据的多少,返回读取的有效字节个数 此处的偏移发生在用户空间,不在内核中。
int available() 返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
void reset()将此流重新定位到上次在此输入流上调用 mark方法时的位置。
void mark(int readlimit)标记此输入流中的当前位置。
boolean markSupported()测试这个输入流是否支持 mark和 reset方法。
下图反应的是用户从内核中读取文件的流程:主要是内用户空间和内核空间的转换
![在这里插入图片描述](http://note.youdao.com/noteshare?id=2a1876053961c108f500b4fed4ec02fd&sub=3C3769535609420DA6A7AEADE8DEBE4A)
以FileInputStream为例
(1)构造方法:
注意:平时多使用传入一个File类型参数的构造方法
FileInputStream(File file)通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(FileDescriptor fdObj)创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
FileInputStream(String name)通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
(2)读写操作的主要方法:
int read( ) //读取一个字节,返回的是这个字节
int read( byte [] b) // 批量读取字节到byte数组中去,返回的是有效个数,如果为空,返回-1;
int read( byte [ ] b , int off , int len ) ; 批量读取字节存到指定数组中,从数组b偏移off个单位后开始存放,len表示存入数据的多少 此处的偏移发生在用户空间,不在内核中。 返回的是有效个数,如果为空,返回-1,
long skip (long n) 跳过并从输入流中丢齐指定大小的字节,发生在内核空间中;
void close( ) :关闭此对象资源;
第一步:创建流对象:
// 文件路径
String path = "E:\\idea_workspace\\9.19\\src\\com\\tulun2\\test2IO\\test";
//第一步:创建流
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(path));
第二步:读取数据: (三种方法)
第一种方法:读取单个字节
// 第一种,使用read()读取单个字节
int read = fis.read(); //读取一个字节 ,返回的是此字节对应码表的下标
System.out.println(read); // 104 ----> h
第二种:批量读取字节
注意:int i =fis.read(b); //返回的是读取的有效字节个数 ,
//第二种:使用read()批量读取数据
byte[] b = new byte[20];
int i =fis.read(b); //使用字节数组批量读取,返回的是读取的有效字节个数
//int i = fis.read(b,4,9) // 把从字节数组4号下标开始,放置9个字节
System.out.println(i); // 20
System.out.println(new String(b)); // hello woui whvo ;
第三种:批量读取其中有效的字节
注意:len = fis.read(b);返回的是也有效字节个数,如果为空返回-1;
//第三种:批量读取其中有效的字节
byte[] b = new byte[5];
//用于接收字节数组的返回值,如果字节数组为空,返回-1,如果不为空,返回的是size
int len = 0;
while ((len = fis.read(b))!=-1) {
String str = new String(b,0,len);
System.out.print(str);
}
第三步:必须关闭资源(流对象)
} catch (IOException e) {
e.printStackTrace();
} finally {
//首先判断此对象是否为null,如果不判断,当对象不存在时会
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、outputStream的使用
描述: outputStream同上,仍然是一个基类,所以使用它的具体实现类来使用,例如FileOutputStream等。
方法探究:
flush( ) : 刷新内核缓冲区
1、建立对象;
注意:
若此文件不存在,将会自动创建此文件,但是路径中的目录必须存在,不如不存在,抛出异常。
若文件存在,则会将原文件覆盖(随机存取文件流可以解决此问题)
//第一步创建文件
File file=new File("hello2.txt");
//第二步创建输出流对象
FileOutputStream fos = null;
try {
fos=new FileOutputStream(file) ;
2、写入数据
注意:write( );
可以使用write逐个写入,也可以用write重载方法传入一个byte类型的数组,所以将此处的string转成了byte的数组
// \n :换行 \t:空格
//传入字节;
fos.write(99); // c
//传字节数组;
fos.write(new String("how are you? \n").getBytes());
//从byte数组中开始偏移,偏移5个,写入10个数据。(是对byte数组进行操作)
fos.write(new String("hello,my brother\n").getBytes(),5,10);
3、关闭流资源(对象)
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}