java中的IO流

来源:互联网 发布:flac数值模拟软件 编辑:程序博客网 时间:2024/06/06 14:13

一 File类

1.1 File类的构造方法

File(String pathname)  //指定文件或者文件夹的路径创建一个File文件。File(File parent, String child) //根据parent文件和child路径名字符串创建File文件。File(String parent, String child) //根据parent路径名和child路径名创建File文件。

目录分隔符 :windows机器上目录分隔符是”\”,在linux机器上的目录分隔符是”/”。为了统一,File类提供了一个separator常量来获取当前系统分隔符。

File file = new File("F:"+File.separator+"a.txt");

路径问题:
1. 绝对路径 : 该文件在硬盘上的完整路径。绝对路径一般都是以盘符开头的。
2. 相对路径 : 相对路径就是资源文件相对于当前程序所在的路径

. 表示当前路径
.. 表示上一级路径

注意 : 写相对路径一定要弄清楚当前程序所在的路径

 File file = new File("."); file.getAbsolutePath();//获取当前程序路径

1.2 File类的常用方法

创建 :

 createNewFile(); //创建一个指定的空文件,如果存在不会再创建 mkdir(); // 指定位置创建目录,只会创建最后一级目录 mkdirs(); // 指定位置创建目录, 会创建路径中所有不存在的目录 renameTo(File dest) //重命名文件或文件夹

删除 :

 delete() //删除一个文件或一个空文件夹 deleteOnExit() //在虚拟机终止时,删除文件,一般用于删除临时文件

判断 :

 isExist() //判读是否存在 isFile() //是否是一个文件 isDirectory() //是否是文件夹 isHidden() // 是否是隐藏的文件或文件夹

获取 :

getName()  //获取文件或文件夹的名称getPath() //返回绝对路径getAbsolutePath() // 获取文件的绝对路径,与文件是否存在没有关系length() //获取文件的大小(字节数)getParent() // 返回文件的父目录的路径名lastModified() //获取最后一次被修改的时间//文件夹相关static File[] ListRoots() //列出所有的根目录(window中就是所有的系统盘符)list() //返回当前文件夹下面的所有子文件名与子文件夹名,包含隐藏文件list(FilenameFilter filter) //返回符合过滤条件的子文件或子目录listFiles() // 返回目录下的文件或目录对象(File类实例)listFiles(FilenameFilter filter) //返回符合过滤条件的子文件或子目录对象(File类实例)

文件名过滤器(FilenameFilter)使用

class MyFilter implements FilenameFilter{  public boolean accept(File dir , String name)  {    //dir:文件目录    //name : 文件名    return false;//定义过滤规则  }}public class Test{ public static void main(String[] args) {   File dir = new File("C:\\test");   //过滤文件   File[] files = dir.listFiles(new MyFilter());  }}

二 IO流

判断使用输出流还是输入流的依据 : 以当前程序作为参照,观察数据是流入还是流出,如果流出则使用输出流,如果数据流入,则使用输入流。

按照处理单位划分为:

字节流 :

字节输入流
字节输出流

字符流 :

字符输入流
字符输出流

2.1 字节流

1 、输入字节流
1.1 FileInputStream(读取文件的输入字节流)

使用FileInputStream读取文件数据的步骤 :

//找到目标文件File file = new File("F:\\a.txt");//建立数据的输入通道FileInputStream fis = new FileInputStream(file);//建立缓冲数组配合循环读取文件的数据byte[] buf = new byte[1024];//一般长度1024//保存每次读到的字节个数int length = 0;//循环读取数据while((length = fis.read(buf))!=-1){}//关闭资源fis.close();//注意 : 异常需要处理,在catch代码块中直接 throw new RunTimeException(e);

1.2 BufferedInputStream (缓冲输入字节流)

BufferedInputStream 的出现主要是为了提高读取文件数据的效率,内部只是维护了一个数组。

BufferedInputStream 使用步骤:

 File file = new File("F:\\a.txt"); FileInputStream fis = new FileInputStream(file); //BufferedInputStream 本身不具备读文件的能力,所以需要借助FileInputStream来读文件 BufferedInputStream bis = new BufferedInputStream(fis); int len = 0; //int len = bis.read(buf) 如果传入了缓冲数组,内容是存储到缓冲数组中,返回值是存储到缓冲数组中的字节个数 while((len=bis.read())!=-1)// 如果使用read方法没有传入缓冲数组,那么返回值是读取到的内容 { } bis.close;//实际上调用的是FileInputStream的close方法//注意 : 异常需要处理,在catch代码块中直接 throw new RunTimeException(e);

2 、输出字节流
2.1 FileOutStream(向文件输出数据的输出字节流)

使用FileOutStream向文件输出数据的步骤 :

// 找到目标文件File file = new File("F:\\b.txt");// 建立数据输出通道FileOutputStream fos = new FileOutputStream(file);//写出数据String data = "hello world";fos.write(data.getBytes());//关闭资源fos.close();

FileOutputStream使用注意细节:

1.使用FileOutputStream,如果目标文件不存在,会自动创建目标文件
2.使用FileOutputStream写数据的时候,如果目标文件已经存在,会先清空目标文件中的数据,然后再写入数据
3.使用FileOutputStream写数据的时候,如果需要在目标文件原来的数据基础上追加数据应该使用new FileOutputStream(file , true)构造函数

2.2 BufferedOutputStream(缓冲字节输出流)

BufferedOutputStream 的出现主要是为了提高输出文件数据的效率,内部只是维护了一个数组。

BufferedOutputStream 使用步骤:

 File file = new File("F:\\a.txt"); FileOutputStream fos = new FileOutputStream(file); int len = 0; BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write("hello world".getBytes()); bos.close;//实际上调用的是FileInputStream的close方法//注意 : 异常需要处理,在catch代码块中直接 throw new RunTimeException(e);

BufferedOutputStream使用要注意的问题 :

使用BufferedOutputStream写数据的时候 ,它的write方法是先把数据写到内部维护的数组中。
使用BufferedOutputStream写数据的时候,它的write方法是先把数据写到内部维护的数组中,如果需要把数据真正的写到硬盘上,需要调用flush方法或者close方法

2.2 字符流

字符流 = 字节流 + 编码(解码)

1、输入字符流

1.1 FileReader 读取文件的输入字符流

使用示例 :

File file = new File("F://a.txt");FileReader fr = new FileReader(file);//建立缓冲字符数组char[] buf = new char[1024];int len = 0;while((len = fr.read(buf))!=-1){  System.out.print(new String(buf,0,len));}fr.close();//注意 : 异常需要处理,在catch代码块中直接 throw new RunTimeException(e);

1.2 BufferedReader(缓冲输入字符流—常用)

BufferedReader 提高读取文件字符的效率和拓展了FileReader的功能,内部维护了一个字符数组。

使用示例 :

File file = new File("F:\\a.txt");//建立数据输入通道FileReader fr = new FileReader(file);//建立缓冲字符流BufferedReader br = new BufferedReader(fr);//readLine() 一次读取一行文本 注意:读取的时候是以"\r\n"为一行的结束标识,但是读到的内容是不包含"\r\n"的。String line = null;while((line=br.readLine())!=null){}br.close();

2、输出字符流

2.1 FileWriter 向文写入件数据的字符流

使用示例 :

File file  = new File("F:\\a.txt");FileWriter fw = new FileWriter(file);String data = @"今天天气很好a";fw.write(data);fw.close();//注意 : 异常需要处理,在catch代码块中直接 throw new RunTimeException(e);

FileWriter使用注意:

1.FileWriter内部是维护了一个1024个字符的数组 , 写数据的时候会先写入到它内部的数组中 , 如果要把数据写到硬盘中,需要调用flush或者close方法
2.使用FileWriter的时候,如果目标文件不存在,会自动创建目标文件。
3.使用FileWriter的时候,如果目标文件已经存在,默认会先清空文件中的数据,如果要在原来的基础上追加数据,需要使用 new FileWriter(file,true) 构造方法

2.2 BufferedWriter (缓冲输出字符流—常用)

BufferedWriter作用 : 提高FileWriter的写数据效率与拓展FileWriter的功能。

使用示例 :

 File file = new File("F:\\a.txt"); FileWriter fw = new FileWriter(file); //建立缓冲输出流对象 BufferedWriter bw = new BufferedWriter(fw); //换行 bw.newLine(); //写出数据 bw.write("大家好a"); bw.close();

2.3序列流

SequenceInputStream

主要作用 : 合并文件

使用示例 :

//需求 : 把a.txt和b.txt中的内容合并到c.txt中File file1 = new File("F:\\a.txt");File file2 = new File("F:\\b.txt");File file3 =new File("F:\\c.txt");//创建对应的输入输出流对象FileOutputStream fos = new FileOutputStream(file3);FileInputStream fis1 = new FileInputStream(file1);FileInputStream fis2 = new FileInputStream(file2);//创建Vector集合存放输入流对象Vector<FileInputStream > vec = new Vector<FileInputStream >();vec.add(fis1);vec.add(fis2);//获取集合的迭代器Enumeration<FileInputStream> enu = vec.elements;//创建序列流对象SequenceInputStream sis = new SequenceInputStream(enu);byte[] buf = new byte[1024];int len = 0;while((len=sis.read(buf))!=-1){  fos.write(buf,0,length);}//流遵循 先开后关,后开先关 的原则sis.close();fos.close();

2.4 对象序列化和反序列化

亦可称为是对象的输入输出流,作用是把对象保存在文件中

2.4.1 对象序列化(ObjectOutputStream)

使用示例 :

class User implements Serializable { private static final long serialVersionUID = 1L;  String name;  int age;  public User(String name,int age)  {    this.name = name;    this.age = age;  }}class Demo { public static voie main(String[] args) {    User user = new User("张三",21);    File file = new File("F:\\user.txt");    FileOutputStream fos = new FileOutputStream(file);    ObjectOutputStream oos = new ObjectOutputStream(fos);    oos.writeObject(user);    oos.close();    fos.close();    }}

2.4.2 对象反序列化(ObjectInputStream)

使用示例 :

class User {  String name;  int age;  public User(String name,int age)  {    this.name = name;    this.age = age;  }}class Demo { public static void main(String[] args) {    File file = new File("F:\\user.txt");    FileInputStream fis = new FileInputStream(file);    ObjectInputStream ois = new ObjectInputStream(fis);   User user =(User) ois.readObject();    ooeadObject();    ois.close(); }}

对象输入输出流要注意的细节:
1. 如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口。 Serializable接口没有任何的方法,是一个标识接口而已。
2. 对象的反序列化创建对象的时候并不会调用到构造方法的、
3. serialVersionUID 是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名、成员、包名、工程名算出的一个数字。
4. 使用ObjectInputStream反序列化的时候,ObjeectInputStream会先读取文件中的serialVersionUID,然后与本地的class文件的serialVersionUID进行对比,如果这两个id不一致,那么反序列化就失败了。
5. 如果序列化与反序列化的时候可能会修改类的成员,那么最好一开始就给这个类指定一个serialVersionUID,如果一类已经指定的serialVersionUID,然后在序列化与反序列化的时候,jvm都不会再自己算这个 class的serialVersionUID了。
6. 如果一个对象某个数据不想被序列化到硬盘上,可以使用关键字transient修饰。
7. 如果一个类维护了另外一个类的引用,那么另外一个类也需要实现Serializable接口。

2.5 Properties(配置文件类)

作用 : 用于生成配置文件与读取配置文件

Properties是Map接口的实现类

保存信息示例 :

 File file = new File("F:\\Person.properties"); Properties pro = new Propertis(); //设置键和值 pro.setProperty("张三""234"); pro.setProperty("李四""789"); //如果Properties中的键值使用了中文,使用store方法生成配置文件的时候只能使用字符流; pro.store(new FileWriter(file),"描述语");

读取信息示例 :

File file = new File("F:\\Person.properties");Properties pro = new Properties();pro.load(new FileReader(file));

Properties使用注意细节:
1. 如果配置文件的信息一旦使用了中文,那么在使用store方法生成配置文件的时候只能使用字符流解决,如果使用字节流生成配置文件的话,默认使用的是iso8859-1码表进行编码存储,这时候会出现乱码。
2. 如果Properties中的内容发生了变化,一定要重新使用Properties生成配置文件,否则配置文件信息不会发生变化。

2.6 打印流(PrintStream)

作用 :

1.打印流可以打印任意类型的数据,而且打印数据之前都会先把数据转换成字符串再进行打印
2.收集异常的日志信息

使用示例 :

File file = new File("F:\\a.txt");PrintStream printStream = new PrintStream(file);//打印任意类型数据printStream.println(97);//收集异常的日志信息File logFile = new File("F:\\2017年10月8日.log")PrintStream logPrintStream = new PrintStream(new FileOutputStream(logFile,true));try{  int c = 4/0;}catch(Exception e){  e.printStackTrace(logPrintStream);} 

System.out 就是 PrintStream对象

2.7 转换流

转换流的作用 :

1.把字节流转换成字符流。
2.使用转换流可以指定编码表进行读写文件。

2.7.1 输入字节流转字符流 (InputStreamReader)

使用示例:

 InputStream in = System.in; //把输入字节流转换成字符流 //指定编码表  new InputStreamReader(InputStream in,String charSet); InputStreamReader isr = new InputStreamReader(in); //字符流的缓冲类 BufferedReader br = new BufferedReader(isr);

2.7.2 输出字节流转字符流(OutputStreamWriter)

使用示例:

File file = new File("F:\\a.txt");FileOutputStream fos = new FileOutputStream(file);//把输出字节流转换成输出字符流//指定编码表  new OutputStreamWriter(OutputStream outString charSet);OutputStreamWriter osw = new OutputStreamWriter(fos);//字符流的缓冲类BufferedWriter bw = new BufferedWriter(isr);