InputStream字节输入流
InputStream就是Java标准库提供的最基本的输入流。它位于java.io这个包中。注意,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类。
FileInputStream文件输入流
FileInputStream是InputStream的一个子类,它是从文件流中读取数据的。
//创建一个基于读取文件的方式的输入流
try(FileInputStream fi=new FileInputStream("D:\\IO流\\21级.txt")){
//读取方式一:
//每次读取一个字节数据,读取至文件末尾时返回-1
//字节数据范围:0-255
int data1=in.read();
int data2=in.read();
int data3=in.read();
//....
System.out.println(data1);
System.out.println(data2);
System.out.println(data3);
//...
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
输出结果:
230
157
168
.....
-1
//创建一个基于读取文件的方式的输入流
try(FileInputStream fi=new FileInputStream("D:\\IO流\\21级.txt")){
//读取方式二:通过循环,读取所有字节数据
int data=-1;
//当文件不为空时
while((data=in.read)!=-1){
System.out.println(data);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
输出结果:
230
157
168
229
157
164
13
10
229
188
160
230
150
135
//写法二:
//创建一个基于读取文件的方式的输入流
try(FileInputStream fi=new FileInputStream("D:\\IO流\\21级.txt")){
//读取方式1:每次读取若干个数据,并保存至一个数组
byte[] buff1=new byte[25600];
int len1=in.read(buff1);
System.out.println("本次读取到的内容:"+Arrays.toString(buff1));
System.out.println("本次读取到的长度:"+len1);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
输出结果:
本次读取到的内容:[-26, -99, -88, -27, -99, -92, 13, 10, -27, -68, -96, -26, -106, -121, -24, -117, -79, 13, 10, -24, -94, -127, -24, -119, -70, -23, -72, -93, 13, 10, -27, -68, -96, -25, -108, -100, -25, -108, -100, 13, 10, -24, -76, -70, -28, -67, -77, -25, -111, -74, 13, 10, -27, -68, -96, -26, -106, -121, -27, -115, -114, 13, 10, -23, -97, -87, -28, -67, -77, -25, -111, -74, 13, 10, -26, -99, -88, -25, -101, -68, -25, -101, -68, 13, 10, -24, -75, -75, -24, -116, -71, 13, 10, -24, -117, -105, -23, -108, -112, -27, -88, -100, 13, 10, -23, -67, -112, -23, -97, -84, -27, -80, -118, 13, 10, -23, -125, -99, -24, -117, -105, -24, -117, -105, 13, 10, -24, -116, -125, -28, -70, -102, -28, -72, -67, 13, 10, -26, -99, -88, -26, -106, -121, -25, -112, -90, 13, 10, -24, -82, -72, -27, -88, -100, 13, 10, -28, -69, -93, -24, -74, -123, -25, -66, -92, 13, 10, -27, -68, -96, -25, -99, -65, -26, -77, -67, 13, 10, -27, -68, -96, -23, -104, -65, -25, -102, -124, 13, 10, -24, -75, -75, -28, -66, -99, -27, -87, -73, 13, 10, -23, -83, -113, -28, -70, -102, -26, -91, -96, 13, 10, -23, -103, -120, -23, -71, -113, -24, -66, -119, 13, 10, -26, -99, -88, -26, -128, -99, -27, -67, -92, 13, 10, -27, -115, -85, -26, -126, -90, -28, -67, -77, 13, 10, -23, -103, -120, -27, -115, -102, -24, -65, -100, 13, 10, -27]
本次读取到的长度:256
//写法二:
//创建一个基于读取文件的方式的输入流
try(FileInputStream fi=new FileInputStream("D:\\IO流\\21级.txt")){
//读取方式二:每次读取每次读取128个数据
byte[] buff2=new byte[128];
int len2=0;
while((len2=in.read(buff2))>0) {
System.out.printf("本次读取到%d个字节:%s\n",len2,
Arrays.toString(buff2));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
输出结果:
本次读取到128个字节:[-26, -99, -88, -27, -99, -92, 13, 10, -27, -68, -96, -26, -106, -121, -24, -117, -79, 13, 10, -24, -94, -127, -24, -119, -70, -23, -72, -93, 13, 10, -27, -68, -96, -25, -108, -100, -25, -108, -100, 13, 10, -24, -76, -70, -28, -67, -77, -25, -111, -74, 13, 10, -27, -68, -96, -26, -106, -121, -27, -115, -114, 13, 10, -23, -97, -87, -28, -67, -77, -25, -111, -74, 13, 10, -26, -99, -88, -25, -101, -68, -25, -101, -68, 13, 10, -24, -75, -75, -24, -116, -71, 13, 10, -24, -117, -105, -23, -108, -112, -27, -88, -100, 13, 10, -23, -67, -112, -23, -97, -84, -27, -80, -118, 13, 10, -23, -125, -99, -24, -117, -105, -24, -117, -105, 13, 10, -24, -116]
本次读取到128个字节:[-125, -28, -70, -102, -28, -72, -67, 13, 10, -26, -99, -88, -26, -106, -121, -25, -112, -90, 13, 10, -24, -82, -72, -27, -88, -100, 13, 10, -28, -69, -93, -24, -74, -123, -25, -66, -92, 13, 10, -27, -68, -96, -25, -99, -65, -26, -77, -67, 13, 10, -27, -68, -96, -23, -104, -65, -25, -102, -124, 13, 10, -24, -75, -75, -28, -66, -99, -27, -87, -73, 13, 10, -23, -83, -113, -28, -70, -102, -26, -91, -96, 13, 10, -23, -103, -120, -23, -71, -113, -24, -66, -119, 13, 10, -26, -99, -88, -26, -128, -99, -27, -67, -92, 13, 10, -27, -115, -85, -26, -126, -90, -28, -67, -77, 13, 10, -23, -103, -120, -27, -115, -102, -24, -65, -100, 13, 10, -27]
本次读取到60个字节:[-120, -104, -28, -67, -77, -23, -99, -103, 13, 10, -24, -75, -75, -25, -66, -114, -25, -66, -92, 13, 10, -27, -68, -96, -26, -76, -117, -26, -76, -117, 13, 10, -24, -76, -70, -27, -68, -96, -27, -82, -127, 13, 10, -27, -68, -96, -27, -106, -122, 13, 10, -23, -69, -114, -23, -111, -85, -23, -101, -88, 10, -24, -75, -75, -28, -66, -99, -27, -87, -73, 13, 10, -23, -83, -113, -28, -70, -102, -26, -91, -96, 13, 10, -23, -103, -120, -23, -71, -113, -24, -66, -119, 13, 10, -26, -99, -88, -26, -128, -99, -27, -67, -92, 13, 10, -27, -115, -85, -26, -126, -90, -28, -67, -77, 13, 10, -23, -103, -120, -27, -115, -102, -24, -65, -100, 13, 10, -27]
在计算机中,类似文件、网络端口这些资源,都是由操作系统统一管理的。应用程序在运行过程中,如果使用了输入输出流对文件进行了读写,完成后要及时关闭,以便于让操作系统把资源释放掉,否则程序占用的资源会越来越多,不但白白占用内存,还影响其他应用程序的运行。所以我们可以调用close()方法手动关闭,也可以将其放入try块中自动进行关闭。
BufferedInputStream缓冲输入流
BufferedInputStream是一个自带缓冲区的输入流,它继承自FilterInputStream。它的本质是通过一个内部缓冲区数组实现的,例如在新建某输入流对应的BufferedInputStream后,我们通过read()方法读取输入流中的数据时,BufferedInputStream会将该输入流的数据分批的填到缓冲区中,每当缓冲区的数据被读取完之后,输入流会再次填充缓冲区,如此反复,直到我们读取完输入流中的数据
FileInputStream fis=new FileInputStream();
//每次read方法,都会产生磁盘的读取
fis.read();
BufferedInputStream in=new BufferedInputStream();
//每次read方法,先在缓冲区读取,如果读取完毕,则统一访问磁盘,进行内容填充
in.read();
//BufferedInputStream可以减少对对磁盘的访问次数
try(BufferedInputStream in=new BufferedInputStream(
new FileInputStream("D:\\IO流") )){
byte[] buff2=new byte[128];//用来存储每次读取到的字节数组
int len2=0;//每次读取到的字节数组的长度
while((len2=in.read(buff2))>0) {
System.out.printf("本次读取到%d个字节:%s\n",len2,
Arrays.toString(buff2));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedInputStream的作用是为其他输入流提供缓冲功能。创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数。BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲中,操作完缓冲区中的这部分数据之后,再从输入流读取下部分的数据。
OutputStream字节输出流
OutputStream和InputStream一样,都是一个抽象类,它有一个最重要的方法就是write(int b)方法,这个方法虽然传入的参数是一个int整数,但是只会写入一个字节,OutputStream和InputStream均是以字节为单位进行输入输出的。
FileOutputStream文件输出流
当我们要实现将指定目录文件读取并重新写入到一个新的目录时,我们既可以一次性将指定目录文件读取完毕再一次性写入,但是这样效率较低。
//完成对指定图片的复制
//写法1:读完再写
try {
byte[] image=Files.readAllBytes(Paths.get("D:\\美女1.jpg"));
//创建文件输出流,将读取的图片复制到新地址。
try(FileOutputStream out=new FileOutputStream("D:\\美女2.jpg")){
out.write(image);
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我们也可以采用“边读边写”的方式,先将读取出的数据放入一个指定长度的字节数组,一旦这个数组被填满,就会将此数组中的内容写入,而不是等全部内容被读取完后再写入。这样效率更高。
//写法2:边读边写
try (FileInputStream in = new FileInputStream("D:\\大美女1.jpg");
FileOutputStream out= new FileOutputStream("D:\\美女1.jpg");){
byte[] buff=new byte[128];
int len=0;
while((len=in.read(buff))>0) {
out.write(buff,0,len);
}
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedStream缓冲输出流
BufferedStream主要是里面包含了一个8192个字节的缓冲区,new BufferedStream(OutputStream out)这个构造方法默认分配的就是一个8192个字节的byte[]数组(即缓冲区),如果要自己指定缓冲区的大小时,可以调用new BufferedStream(OutputStream out,int size)这个构造方法。
//BufferedOutputStream :边读边写
try(BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("D:\\大美女1.jpg"));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("D:\\IO流\\美女1.jpg"))){
byte[] buff=new byte[128];
int len=0;
while((len=bis.read(buff))>0) {
bos.write(buff,0,len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}