字节流基类的探究

字节流基类包括 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();
    }
}

你可能感兴趣的:(IO流部分)