Fork me on GitHub

JAVA中的流(续)

一、流(Stream)

所谓流(Stream),就是一系列的数据。

当不同的介质之间有数据交互的时候,java就会使用流来实现。

数据源可以使文件,还可以是数据库,网络,甚至是其他的程序

不如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流

  • 字节输入流:InputStream

  • 字符输入流:Reader    

  • 缓存字符输入流:BufferedReader  
  • 数据输入流 :DataInputStream

  • 字节输出流:OutputStream        

  • 字符输出流:Writer    
  • 缓存字符输出流:PrintWriter    
  • 数据输出流:DataOutputStream 

img

1、文件输入流

可以用来把数据从硬盘的文件,读取到JVM(内存)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream{
public static void main(String[] args){
try{
File f=new File("d:/lol.txt");
//创建基于文件的输入流
FileInputStream fis=new FileInputStream(f);
//通过这个输入流,就可以把数据从硬盘,读取到java的虚拟机中,也就是读取到内存中
}catch(Exception e){
e.printStackTrace();
}
}
}

2、字节流

  • InputStream:字节输入流

  • 用以字节的形式读取和写入数据

  • InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。

  • FileInputStream是InputStream的子类,可以进行直接使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream{
public static void main(String[] args){
try{
File f=new File("d:/lol.txt");
//创建基于文件的输入流
FileInputStream fis=new FileInputStream(f);
//通过这个输入流,就可以把数据从硬盘,读取到java的虚拟机中,也就是读取到内存中
//创建字节数组,其长度就是文件的长度
byte[] all=new byte[(int)f.length()];
//以字节流的形式读取文件所有内容
fis.read(all);
for(byte b:all){
System.out.println(b);
}
//每次使用完流,都应该进行关闭
fis.close()
}catch(Exception e){
e.printStackTrace();
}
}
}
  • OutputStream:字节输出流,同事也是抽象类,只提供方法声明,不提供方法的具体实现。

  • FileOutputStream是OutputStream子类,可以进行直接使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream{
public static void main(String[] args){
try{
File f=new File("d:/lol.txt");
byte data[]={88,89};
//创建基于文件的输出流
FileOutputStream fos=new FileOutputStream(f);

//把数据写入到输出流上
fos.write(data);
//每次使用完流,都应该进行关闭
fos.close()
}catch(Exception e){
e.printStackTrace();
}
}
}

注:所有的流,不论是输入流还是输出流,使用完毕之后,都应该关闭,如果不关闭,会产生对资源占用的浪费,当量比较大时,会影响业务的正常开展。

3.流的关闭方式

在finally中关闭:

  • 首先把流的引用声明在try的外面,如果声明在try里面,其作用与无法抵达finally

  • 在finally关闭之前,要先判断该引用是否为空

  • 关闭的时候,要再一次的进行try。。catch处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream{
public static void main(String[] args){
File f=new File("d/source/LOL.exe");
FileInputStream fis=null;
try{
fis=new FileInputStream(f);
byte[] all=new byte[(int)f.length()];
fis.read(all);
for(byte b:all){
System.out.println(b);
}
}catch(IOException e){
e.printStackTrace();
}finally{
//在finally里关闭流
if(null!=fis)
try{
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}

使用try()方式

  • 把流定义在try()里,try,catch或者finally结束的时候,会自动关闭

  • 这种编写代码的方式叫做try-with-resources,这是JDK7开始支持的技术

  • 所有的流,都实现了一个接口叫做AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化,并且在try,catch,finally结束的时候自动关闭,回收相关资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestStream{
public static void main(String[] args){
File f=new File("d/source/LOL.exe");
//把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
try(FileInputStream fis=new FileInputStream(f)){
byte[] all=new byte[(int)f.length()];
fis.read(all);
for(byte b:all){
System.out.println(b);
}catch(IOException e){
e.printStackTrace();
}
}
}
}