一、流的概念
流是一组有序的数据序列,根据操作类型,分为输入流和输出流,I/O流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然与磁盘文件存取有关,但是程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口等。
java语言定义了许多类专门负责各种方式的输入/输出,这些类都在java.io包中。其中所有输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类
二、字节流和字符流
计算机上所有文件存储都是字节(byte),而java内用Unicode编码存储字符,字符流处理的单元是2个字节的Unicode字符,分别操作字符、字符数组或字符串;字符流处理单元为1个字节,操作字节和字节数组。
字节流在操作时不会用到缓冲区(内存),文件本身直接操作,而字符流会使用缓冲区,通过缓冲区再操作文件。
如果是音频文件、图片、歌曲,就用字节流好点
如果是关系到中文(文本)的,用字符流好点
三、文件类(File)
1、文件实例(三种方法,第一种较常用)
File file1=new File("D:/test.txt");//路径名称(包含文件名)
File file2=new File("test.txt");//文件名,当前目录下
File file3=new File("D:/doc","test.txt");//父路径,子路径 都是String类型
2、获取文件信息
- getName():获取文件名称,返回String
- canRead():boolean类型,是否可读
- canWrite():...
- exist()/isFile():boolean类型,是否存在
- length():long,文件长度,以字节为单位
- getAbsolutePath():文件绝对路径,返回String
- getParent():文件父路径,返回String
- isDirectory():boolean 是否为目录
- isHidden():boolean是否隐藏
- lastModified():long,最后修改时间
- delete():删除文件
- createNewFile():通过实例创建文件
四、文件输入输出流类
流程:使用File类打开一个文件——通过字节流、字符流的子类,指定输出位置——进行读写操作——关闭输入输出流
注:IO操作属于资源操作,操作结束后一定记得关闭,字节流在操作文件时,即使不关闭资源(close),文件也能输出;但是字符流不使用close方法,不会输出任何内容,因为字符流使用的是缓冲区。这里可以用flush方法强制刷新缓冲区,也可以不关闭直接输出(不推荐这么干。。。)
所有涉及缓存的(字符写入流,BufferedInputStream等等)在close之前用flush方法,要养成习惯。
注:缓冲功能的流的原理是在普通流基础上多了个缓冲区,当读写数据达到一定量时,在自动往文件里进行读写,如果没有装满缓存区文件就读写完毕,那这个时候需要手动将缓冲区数据读写到目标位置,这个手动的过程,就是flush方法。(如果没装满,就读写完毕,会丢失数据的哦)
1、字节流
InputStream类:是字节输入流的抽象类,所有字节输入流的父类 eg:BufferedInputStream,FileInputStream等
常用方法如下:
- read():读取数据的下一个字节,返回0~255的int字节值,如果已达到流末尾而没有可用字节,返回-1
- read(byte[] b):输入流读取一定长度的字节,并以整数形式返回字节数
- close():关闭流
OutputStream类:是字节输出流的抽象类,所有字节输出流的父类 eg:BufferedOutputStream,FileOutputStream等
常用方法如下:
- write(int b):将指定字节写入输出流
- write(byte[] b):将b个字节从指定byte数组写入此流
- write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始len个字节写入流
- flush():彻底完成输出并清空缓存区
- close()
BufferedInputStream、BufferedOutputStream:带缓存的输入输出流
FileInputStream:以字节流方式读取,FileOutputStream以字节流方式写入;
注:操作数据是byte[] b数组
2、字符流
最初java不支持文本文件处理,后来引入Reader和Writer两个类
Reader类:是字符流输入流的抽象类,所有字符输入流的父类 eg:BufferedReader,InputStreamReader,FileReader等
Writer类:是字符流输出的抽象类,所有字符输出流的父类 eg:BufferedWriter,OutputStreamWriter,FileWriter等
注:操作数据是char[] c数组,String str字符串
eg:while((ch = filereader.read())!=-1 )循环来读取文件字符;while((data = bufferedreader.readLine())!=null) 循环读取文件行
字节流是最基本的,处理二进制数据,由于实际中更多的数据是文本,又有了字符流的概念,按照虚拟机的encode来处理,二者之间可以通过InputStreamReader和OutputStreamWriter转换,将读写的字节流,转换为字符流,大部分乱码中文的本质原因都是字节流和字符流转换不统一造成的,常用读写方法如下:
File file = new File ("hello.txt");
FileInputStream in=new FileInputStream(file); //字节流
File file = new File ("hello.txt");
FileInputStream in=new FileInputStream(file); //字节流
InputStreamReader inReader=new InputStreamReader(in,"utf-8"); //转换流
BufferedReader bufReader=new BufferedReader(inReader); //字符流 ,可按行读写
File file = new File ("hello.txt");
FileReader fileReader=new FileReader(file); //字符流,可按行读写
BufferedReader bufReader=new BufferedReader(fileReader);
字节,字符,字符串相互转换如下:
//字符串转换为byte,char数组
String str = "abcd";
byte[] b = str.getBytes();
char[] ch= str.ToCharArray();
//byte转换为字符串
byte[] b = {97,98,100};
String s = new String(bs1);
//char转换为字符串
char[] ch=new char[]{'s','2','中'};
String cs = new String(ch);
在实际项目中,可根据项目需求,去选择文件读写的方式。