FileInputStream-FileOutputStream:
1.构造方法:
new ( "文件的 绝对路径/相对路径" ) ;
//注意构造方法的参数是字符串类型
//绝对路径为带磁盘目录的,如:C:\java-prictice\javaseplus\text
//相对路径:(IDEA默认当前路径:当前模块的根)+相对路径
//通过“电脑”复制文件位置的时候,要在上边的那个路径的后面+ “\具体文件名”,否则此路径只是代表你看到界面的上一个目录;
//把路径粘贴到构造方法里的时候,IDEA工具会自动把“ \ ”转换为“ \\ ”,实际上,把“ \\ ”改为“ / ”也是正确的;
FileInputStream 引用文件,代表将此文件作为读的对象;
FileOutputStream 引用文件,代表将此文件作为写的对象(输出在此文件中),若此文件不存在,则会自动创建;
2.常用方法:
1)FileInputStream . read ( bytes数组 ) //读取流的字节,并将读取的字节放到byte数组里,返回读取字节个数(int)[ 若读到文件末尾,则返回-1 ]
2)FileInputStream . available ( int ) //返回流当前未读取的字节个数
3)FileInputStream . skip ( int ) //跳过几个字节不读
3.注意:
1)为方便 finally语句中对流的关闭,所以一般在try外边声明空指针引用,在try里边new流对象;
2)声明的byte数组长度不宜过长,因为内存中很难找到一条特别长的连续空间;
3)每个流不能一起(并列)关闭,避免出现异常导致有些流无法关闭;
4.拷贝文件:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; //File字节流拷贝 public class FileInputStreamTest { public static void main(String[] args) { //声明 FileInputStream 引用为空 FileInputStream fis=null; //声明 FileOutputStream 引用为空 FileOutputStream fos=null; //拷贝的重要操作(抛出异常的部分)放到try-catch里 try { //创建文件字节输入流 fis=new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt"); //创建文件字节输出流 fos=new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugFISCopy.txt",true); //创建长度为100的数组bytes,元素类型为byte(字节) byte [] bytes=new byte[100]; //声明“读取字节个数”的变量 int readCount; //读取fis的“bytes.length”个字节,同时判断是否退出循环 //循环退出条件:读取字节个数为 -1 while ((readCount=fis.read(bytes))!=-1){ //将此时bytes里装的字节写入fos对象里 fos.write(bytes,0,readCount); } //刷新输出流 fos.flush(); } catch (FileNotFoundException e) {//用IDEA工具生成 e.printStackTrace(); } catch (IOException e) {//用IDEA工具生成 e.printStackTrace(); } finally {//fis与fos分开关闭,避免彼此的影响 if (fis!=null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos!=null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
FileReader-FileWriter:
1.构造方法:
FileReader 构造方法参考 《FileInputStream-FileOutputStream》
FileWriter 构造方法:
//此流的writer方法,会将写的字符覆盖整个文本(原文件中的字符会被删除,然后录入写的字符) FileWriter fileWriter1=new FileWriter("C:\\Program Files\\Git\\bin"); //此流的writer方法,会将写的字符添加到文本后面(原文件中的字符不变) FileWriter fileWriter2=new FileWriter("C:\\Program Files\\Git\\bin",true);
2.常用方法:
参照 《FileInputStream-FileOutputStream》与下面的《拷贝文件》;
3.注意:
字节流拷贝文件时,数组声明为byte类型,那用字符流时,自然就声明为char类型;
字符流绑定的文件格式只能是“ . txt ” 格式;
4.拷贝文件:
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; //File字符流拷贝 public class FileWriteTest { public static void main(String[] args) { FileReader in=null; FileWriter out=null; try { in=new FileReader("C:\\java-prictice\\javaseplus\\pra\\debug.txt"); out=new FileWriter("C:\\java-prictice\\javaseplus\\pra\\debugFWCopy.txt",true); char [] chars=new char[3]; int readCount; while ((readCount=in.read(chars))!=-1){ out.write(chars,0,readCount); } out.flush(); } catch (IOException e) { e.printStackTrace(); }finally { if (in!=null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out!=null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
BufferedReader-BufferedWriter:
1.BufferedReader,BufferedWriter,都是自带缓冲的流,换句话说,不需要提供数组,也可以拷贝文本;
2.构造方法:
BufferedReader 参数:字符输入流(FileRead)
BufferedWriter 参数:字符输出流(FileWriter)
InputStreamReader 参数:字节输入流(FileInputStream)//将字节输入流转换为字符输出流
OutputStreamWriter 参数:字节输出流(FileOutputStream)//将字节输出流转换为字符输出流
综上,可以这么写:
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt"))); BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true)));
3.常用方法:
BufferedReader . readLine ( ) //读取流当前行
BufferedWriter . write ( ) //写入流当前行
4.拷贝文件代码:
import java.io.*; //Buffered字符流拷贝 public class BufferedReadTest { public static void main(String[] args) { BufferedReader br=null; BufferedWriter bw=null; try { br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt"))); bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true))); String read; while ((read=br.readLine())!=null){ bw.write(read); //让文本一行一行的写出来 bw.write("\n"); } bw.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw!=null){ try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
DataOutputStream-DataInputStream:
1.DataOutputStream,DataInputStream 都是数据专属流,这个流可以将数据连同数据的类型一并写入文件;
2.注意:
DataOutputStream 写的文件,只能用 DataInputStream 去读,并且读的时候,读的顺序必须和写的顺序一样,才可以正常取出数据;
专属流读和写的文件都不是普通文档(用记事本看不到正常信息);
3.“读写”训练:
import java.io.*; public class DataOutputStreamTest { public static void main(String[] args) { DataOutputStream dos=null; DataInputStream dis=null; try { dos=new DataOutputStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt",true)); dis=new DataInputStream(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt")); byte b=100; short s=200; int i=300; long l=400l; float f=500.0f; double d=600.0; boolean sex=true; char c='c'; dos.writeByte(b); dos.writeShort(s); dos.writeInt(i); dos.writeLong(l); dos.writeFloat(f); dos.writeDouble(d); dos.writeBoolean(sex); dos.writeChar(c); dos.flush(); System.out.println(dis.readByte()); System.out.println(dis.readShort()); System.out.println(dis.readInt()); System.out.println(dis.readLong()); System.out.println(dis.readFloat()); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); System.out.println(dis.readChar()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (dis!=null){ try { dis.close(); } catch (IOException e) { e.printStackTrace(); } } if (dos!=null){ try { dos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
100 200 300 400 500.0 600.0 true c Process finished with exit code 0
PrintStream:
1.PrintStream 属于标准字节输出流,默认输出到控制台上;
2.举个栗子:
import java.io.PrintStream; public class pra{ public static void main(String[] args) { PrintStream ps=System.out; ps.println("输出到控制台上"); } } 运行结果: ------------------------ 输出到控制台上 Process finished with exit code 0
3.改变 PrintStream 的输出方向:
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; public class PrintStreamTest { public static void main(String[] args) { //向日志中导入msg字符串 Logger.log("调用了 System 的 gc() ,建议启动垃圾回收器"); Logger.log("调用了 UserSystem 的 book()"); Logger.log("用户尝试登录,验证失败"); } } //日志类 class Logger { public static void log(String msg) {//获取字符串msg //声明空引用 PrintStream printStream=null; try { //printStream流 绑定此文件 printStream = new PrintStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\log.txt",true)); //改变System.out的输出方向(输出的东西会进入printStream流) System.setOut(printStream); //获取此时刻时间 Date nowTime =new Date(); //自定义时间格式 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); //将nowTime转换为我们的自定义格式,然后将msg字符串拼接上,最后输出 System.out.println(sdf.format(nowTime)+" : "+msg); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
4.注意:标准输出流不需要手动 clsoe 流;
File 类:
1.概述:File 类与IO流四大家族无继承关系,所以File类不能完成文件的读与写;
2.构造方法:new ( " 路径 " ) ;
3.常用方法:
引用 . createNewFile ( ) //在指定位置创建一个空文件(成功就返回true,如果已存在就不创建,然后返回false)
引用 . mkdir ( ) // 在指定位置创建一个文件夹
引用 . mkdirs ( ) // 在指定位置创建一个多重文件夹
引用 . exists ( ) // 判断文件或文件夹是否存在
引用 . isFile ( ) // 判断是否是一个文件,返回 boolean
引用 . isDirectory ( ) // 判断是否是一个目录,返回 boolean
引用 . getAbsolutePath ( ) // 获取文件的绝对路径,与文件是否存在没关系
引用 . getParent ( ) // 返回此文件路径的父路径(String),如果此路径名没有指定父目录,则返回null
引用 . getName ( ) // 获取文件或文件夹的名称,不包含上级路径
引用 . length ( ) // 返回此文件大小(字节)
引用 . lastModified ( ) // 获取文件最后一次被修改的时间
引用 . listFiles ( ) // 返回当前目录下的所有子文件(返回值类型为 FIle数组)
ObjectInputStream-ObjectOutputStream:
此体系知识请参考《上边的》
结合栗子理解:
import java.io.*; import java.util.ArrayList; import java.util.List; public class ObjectInputStreamTest { public static void main(String[] args) throws Exception{//将所有异常抛出 //ObjectOutputStream 绑定Cars文件(若无则新建) ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Cars")); //ObjectInputStream 绑定已存在的Cars文件 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Cars")); //创建专门装Car的集合cars List<Car> cars=new ArrayList<>(); //向cars集合中添加元素 cars.add(new Car(1,"大众")); cars.add(new Car(2,"法拉利")); cars.add(new Car(3,"丰田")); //将集合cars写入oos绑定文件中(反序列化) oos.writeObject(cars); //读取ois绑定文件中的所有对象(序列化),并强转为List<Car>类型,最后将所有对象装到carsList集合中 List<Car> carsList= (List<Car>) ois.readObject(); //遍历carsList集合 for (Car car:carsList) { System.out.println(car); } oos.flush(); oos.close(); ois.close(); } } class Car implements Serializable{ private static final long serialVersionUID = -2630683108946058933L; private int no; private String brand; public Car() { } public Car(int no, String model) { this.no = no; this.brand = model; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getModel() { return brand; } public void setModel(String model) { this.brand = model; } @Override public String toString() { return "Car{" + "no=" + no + ", model='" + brand + '\'' + '}'; } } 控制台输出结果: --------------------------- Car{no=1, model='大众'} Car{no=2, model='法拉利'} Car{no=3, model='丰田'} Process finished with exit code 0
序列化 / 反序列化:
1.概述:
2.自定义的类需要实现 Serializable 接口,才支持序列化和反序列化;
3.序列化版本号:
实现了 Serializable 接口的类,系统会为其自动生成一个序列化版本号,但是最好咱们手动生成版本号,举个栗子:
import java.io.Serializable; class Car implements Serializable{ private static final long serialVersionUID = 8342087006090942735L; }
java虚拟机识别一个类,首先看类名,其次看序列化版本号;
4.被 transient 关键字修饰的属性不参与序列化:
private transient String name;
IO+Properties:
1.优点:
对于以后需要经常改变的数据,可以单独写到一个文件中,使用程序动态读取;将来只需要修改这个文件的内容, java代码不需要改动,不需要重新编译,服务器也不需要重启,就可以拿到动态的信息;类似这种机制的这种文件被称为配置文件;
2.当配置文件中的内容格式为:
key1=value
key2=value
我们把这种配置文件叫做属性配置文件;
3.注意:
java 规范中有要求:属性配置文件建议以 “ . properties ”结尾;这种以 ”. properties “结尾的文件在java中被称为:属性配置文件;
Properties 是专门存放属性配置文件内容的一个类;
4.栗子老师:
import java.io.FileReader; import java.util.Properties; public class IOProperties { public static void main(String[] args) throws Exception{ //FileReader绑定文件 FileReader reader=new FileReader("C:\\java-prictice\\javaseplus\\pra\\IOPropertiesTest.txt"); Properties pro=new Properties(); //将FileReader绑定文件载入Pro集合 pro.load(reader); //通过key获取value System.out.println(pro.getProperty("username")); System.out.println(pro.getProperty("password")); System.out.println(pro.getProperty("data")); System.out.println(pro.getProperty("不存在的key,会输出 null")); } } 运行结果: ----------------------------- a01 123456a01 null null Process finished with exit code 0
随笔:
节点流:本身作为包装流的构造方法的参数;
包装流:包装流的构造方法的参数是节点流;