IO字节流

Posted dudu0411

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO字节流相关的知识,希望对你有一定的参考价值。

IO技术:

      它主要的功能就是把我们程序中的数据可以保存到程序以外的其他持久设备中(如:我们电脑的硬盘),或者从其他持久设备中(如:我们电脑的硬盘)进行读取数据,把数据读取到我们的Java程序中。

IO:

I:Input:输入或者读取,从持久设备(硬盘)的数据放到内存中;

O:Output:输出或者写出,从内存中的数据放到持久设备(硬盘)上;

也可以按照如下理解:

把从持久设备(硬盘)上读取(输入)到内存中的动作,称为读操作。 I:input。

把内存中的数据输出(写出)到持久设备(硬盘)的动作,称为写操作。O:output。

IO流

分为字节流,字符流

字节流:字节为单位读写数据,可以对任意类型的文件进行读写操作

字节输入流 InputStream   (输入流:读取数据,把持久设备的数据读取到内存中)
字节输出流 OutputStream(输出流:写出数据,把内存的数据写出到持久设备)

读写:
读:从持久设备上给程序读取数据(硬盘->内存)
写:把程序中数据写到持久设备上(内存->硬盘)

字节输出流 OutputStream

        是抽象的不能创建对象 通过子类创建对象 FileOutputStream的对象把数据写到文件中

常用方法:

 close方法是关闭Java和其他设备之间的连接。

 write方法是把数据写到Java关联的设备中

 write( byte[] b ) 把这个b字节数组中的所有数据写到关联的设备中(设备包括文件、网络或者其他任何地方)。

write( byte[] b , int off , int len ) 把b字节中的数据从下标off位置开始往出写,共计写len个

 write( int b ) 把这个b数据写到关联的设备中

代码:

File files=new File("D:\ab\aa.txt");
//OutputStream
OutputStream out=new FileOutputStream(files);
byte[] b={2,23,22,90};
//将数组中的数据写入到指定的文件中
out.write(b);
//关闭输出流
out.close();

操作完成后为什么要close?

A:流关闭后,就会释放系统资源;
B:流关闭,就变成了垃圾数据,这样可以被垃圾回收器回收,免得没有用的资源浪费空间;

想换行,可以在数据的末尾加: (windows)
String separator = System.getProperty("line.separator");//获取系统中的行分割符

字节输入流InputStream

从文件(硬盘)中向内存中读取数据,需要使用输入流对象:InputStream,于InputStream类是抽象类,不能创建这个类的对象,如果想要创建对象,那么只能创建InputStream类的子类。

方法:

read();//默认读取一个字节

read(byte[] b);//指定读取字节的个数,并存在缓冲区中

read(byte[] b,int off,int len);//将输入流最多len个数据字节读入到byte数组中

说明:

1)read():调用一次read,就可以从关联的文件中读取一个字节数据,并返回这个字节数据。

2)read():方法可以从关联的文件中读取数据。所有read方法如果读取到文件的末尾,都会返回-1。遇到-1就代表文件中的数据已经被读取完毕。

3)read(byte[] b) :调用一次,读取多个字节数据,把读到的字节数据保存在传递的b字节数组中。返回字节数组中读取的字节个数。注意啦:这个返回值不是数组长度。

File files=new File("D:\ab\aa.txt");
//InputStream是抽象类不能创建对象,只能创建子类对象
InputStream in=new FileInputStream(files);
//InputSteam读取文件中的字节数据,所以输入流必须指定的是文件,
//使用read读取的是第一个字节第一个数据;
/* int i=in.read();
System.out.println("输入流读取字节"+i);
//第二次读取
int i2=in.read();
System.out.println("输入流读取字节"+i2);*/
int b1=0;
//将in.read();读取到的字节保存到b1中
//如果b1等于-1说明已读到最后一个字节,否则文件中还有数据
while((b1=in.read())!=-1){
System.out.println((char)b1);
}
in.close();
----------------将一个文件中的数据复制到另一个文件中----------------------------------
//创建一个输入流,一个输出流
InputStream input= new FileInputStream("D:\ab\aa.txt");
OutputStream output=new FileOutputStream("D:\ab\a2.txt");
int b2=0;
if((b2=input.read())!=-1){
output.write(b);
}
input.close();
output.close();

注意

1.由于输入流读取的是文件中的字节数据,要求输入流指定一定是文件,不能是文件夹,否则会报异常
2.在构造函数中指定的文件一定要在硬盘上存在,否则会报异常

3)流的关闭动作,必须被执行。但是如果在流关闭之前,已经出异常,那么流的关闭动作无法执行。
必须被执行的动作,放到finally中;把关闭动作,放到finally代码块中后,流的定义也必须放到try块的外面,否则看不到;在finally中关闭流的时候要先判断流是否为null,如果不判断那么流对象调用close()函数有可能报空指针异常。

字节流缓冲区

字节缓冲区分为:输出流缓冲区BufferedOutputStream,字节输入缓冲区:BufferedInputStream

字节输入缓冲区:该流需要使用输入流对象读取字节数据,把读取到字节数据暂时存储在缓冲区对象内部的数组(缓冲区)中,当内部的缓冲区数组存满了后或不需要再读取数据了,就可以从内部的缓冲区数组中获取字节数据,它内部维护一个数组,可以从底层读取多个数据

//创建输入流对象
FileInputStream file=new FileInputStream("D:\ab\aa.txt");
//创建输入流缓冲区,读取底层输入流对象
BufferedInputStream bfis=new BufferedInputStream(file);
//创建数组
byte[] b=new byte[1024];
//定义一个变量
int len=0;
while((len=bfis.read())!=-1){
System.out.println(new String(b,0,len));
}
//关闭资源
bfis.close();//直接关闭缓冲区就可以,不用手动关闭字节流,因为底层已关闭输入流

问题:为什么缓冲区流需要接收一个普通字节流呢?

缓冲区流是为了 高效而设计的,缓冲区流本身仅仅是维护了一个数组。不具备读和写的功能。真正的读写还是要依赖普通的字节流。

为什么使用缓冲区:
1.使用缓冲区的时候,后期需要数据的时候,不直接和文件进行交互,而是和缓冲区索要数据
2.缓冲区只能临时存储数据,不能从底层读取数据,从底层读取数据需要输入流
3.使用缓冲区的目的是提高读写效率,先使用FileInputStream输入流将硬盘上的文件读取到缓冲区中,然后在缓冲区中的数组中取出数据存放到我们定义好的数组中,以为连个数组都是在内存中,这样交互数据会更快一点
4,不是用缓冲区时,是从硬盘上直接将数据读取到定义好的数组中,这样效率会低点

//创建一个可以直接和文件进行交互的输入流对象

        FileInputStream fis = new FileInputStream("D:\test\123.txt");

        //创建输入流缓冲区,指定可以从底层读取数据的流对象

        BufferedInputStream bufin = new BufferedInputStream(fis);

        //创建数组

        byte[] b=new byte[1024];

        //定义一个变量

        int len=0;

        while((len=bufin.read(b))!=-1)

        {

            System.out.println(new String(b,0,len));

        }

        //关闭资源

        bufin.close();

说明:上述代码关闭缓冲区流就可以了,不用手动关闭字节流了,因为在底层已经关闭字节流了。

字节输出缓冲区:BufferedOutputStream

构造方法摘要 :BufferedOutputStream(OutputStream out)

BufferedOutputStream:该流需要使用输出流对象写入字节数据,把要写入的数据转换为字节数据后暂时存储到缓冲区数组中,当内部缓冲区数组存满后或者关闭流资源或者刷新缓冲区时就可以从缓冲区数组取出字节数据写入到文件中,

//创建输出流对象
FileOutputStream fos=new FileOutputStream("D:\ab\aa.txt");
//创建输出流缓冲区
BufferedOutputStream bos=new BufferedOutputStream(fos);
//写入数据
bos.write("hello 上海传智哈哈".getBytes());
//关闭输出流缓冲区
//bos.close();
//将缓冲区的数据刷新输出流中
bos.flush();

注意:

flush:刷新缓冲区,把缓冲区中的有效数据刷到底层文件中,刷新完成之后,缓冲区流还可以继续使用。
close:关闭流和底层文件之间的关联,一旦流关闭了,就不能在使用。

当缓冲区写满,或者我们手动调用flush方法,或者最后我们关流,才会把缓冲区中的数据一次性的写到底层文件中

小结:
字节流缓冲区对象属于IO流中的高效流,可以提高文件的读写效率

















以上是关于IO字节流的主要内容,如果未能解决你的问题,请参考以下文章

字节流与字符流的简单应用

IO编程__字节流__输入

IO编程__字节流__输出

JAVA IO 字节流 FileInputStream FileOutputStream

IO流24 - 字节流 - 字节流的四种复制文件方式对比

IO编程__字节流__输入输出__图片移动