目录
一.对象流
二.字符流
2.1字符节点流
2.2 字符缓冲流
2.3 打印输出流
2.4 字符转换流
2.5 IO流汇总
三.File类
3.1 File类常用方法
3.2 创建不存在父级目录的文件
3.3 查找当前层的txt文件
3.4 递归操作文件
//对象流: ObjectOutputStream/ObjectInputStream //1. 也是一个处理流,是一个带缓冲区的流 //2. 增加了存储对象的功能 =========================对象流存单个对象======================== //案例: 对象流存储自定义对象 //存储自定义对象的类,必须实现序列化,才可通过对象流存储 //Serializable:标记型接口,无需实现重写方法 class Person implements Serializable{ private String name; public Person(String name) { this.name=name; } @Override public String toString() { return "Person [name=" + name + "]"; } } public class Test1 { @Test //单元测试,只需在成员方法中+@Test public void writeTest() throws FileNotFoundException, IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")); //oos.writeObject(new String("zsf")); //存字符串 oos.writeObject(new Person("zsf")); //存自定义对象-序列化 oos.close(); } @Test public void readTest() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")); //String person = (String)ois.readObject(); Person person = (Person) ois.readObject(); //反序列化 System.out.println(person); ois.close(); } } =====================对象流存多个对象====================== //1.在对象流中可以设置某些属性不参与序列化--transient,static //2.读写多个对象的问题 //方式1:捕获异常 //方式2:使用集合存储 //细节:字节节点流可以往文件追加内容,所以,处理流,字节缓冲流,对象流都可以追加内容 //追加内容往往只用在存日志中(且更多的是字符流存日志-效率更高) class Student implements Serializable{ //产生序列化版本ID,在版本升级时,能唯一识别 private static final long serialVersionUID = -5702534791901064731L; private String name; private /*transient*/ /*static*/ int age; //transient,static:修饰该属性不参与序列化 public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } public class Test2 { @Test //注意:当前包中一定不能有Test类 public void writeTest() throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt", true)); //方式1:直接存多个对象,获取时捕获异常 /*oos.writeObject(new Student("zsf", 30)); oos.writeObject(new Student("ls", 34)); oos.writeObject(new Student("ww", 35)); */ //方式2:存集合 List<Student> list = new ArrayList<Student>(); list.add(new Student("zsf", 30)); list.add(new Student("ls", 34)); oos.writeObject(list); oos.close(); } @Test public void readTest() throws ClassNotFoundException, IOException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")); //方式1:捕获异常 /* try { while(true) { Student st = (Student) ois.readObject(); System.out.println(st); } } catch (Exception e) { }finally { ois.close(); }*/ //方式2:通过集合获取 List<Student> list = (List<Student>) ois.readObject(); System.out.println(list); ois.close(); } }
字符流: 通过一个字符一个字符读写,效率比字节流高,但只能读写文本文件
抽象父类: Writer/Reader
//字符节点流:FileWriter/FileReader(富二代流) //特点:可以追加存储,及简化代码量 public class Test1 { @Test public void writeTest() throws IOException { FileWriter fw = new FileWriter("a.txt",true); //参数2:追加 fw.write("hello,world"); fw.close(); } @Test public void readTest() throws IOException { FileReader fr = new FileReader("a.txt"); char[] cbuf = new char[1024]; int len=fr.read(cbuf); System.out.println(new String(cbuf,0,len)); fr.close(); } }
//字符缓冲流: BufferedWriter/BufferedReader //带缓冲的字符流,读写效率非常高 //提供了两个非常常用的方法,读写换行:newLine/readLine public class Test1 { @Test public void writeTest() throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt")); for(int i=0;i<5;i++) { bw.write("好好学习..."+i); bw.newLine(); //写内容换行 } bw.close(); } @Test public void readTest() throws IOException { BufferedReader br = new BufferedReader(new FileReader("a.txt")); String msg; while((msg=br.readLine())!=null) { System.out.println("打印:"+msg); } } }
//PrintWriter: 输出字符流 , 输出内容到文件 //具有print/println等方法,用于打印换行 //支持原样打印 public class Test1 { public static void main(String[] args) throws FileNotFoundException { PrintWriter pw = new PrintWriter("a.txt"); pw.println(66); pw.println(3.14); pw.close(); //PrintStream:输出字节流 系统调的,输出到系统的控制台 //PrintWriter与PrintStream都是打印输出流,只不过一个是字节流,一个是字符流 System.out.println(66); System.out.println(3.14); } }
//字符转换流: OutputStreamWriter/InputStreamReader //该类直接从字节流转换到字符流的 //转换流可以进行乱码处理: 用什么编码写,那么就用什么编码读,才不会出现乱码 public class Test2 { @Test public void writeTest() throws IOException { //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt")); //字符转换流,可以进行读写时编码设置 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"GBK"); osw.write("hello,io流"); osw.close(); } @Test public void readTest() throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK"); char[] cbuf = new char[1024]; int len = isr.read(cbuf); System.out.println(new String(cbuf,0,len)); isr.close(); } }
//File类:IO流是基于文件内容的读写; File类用于操作文件或目录的本身信息 //File类的常用方法: //只需要指定好File对象的路径,则可知道该对象的信息 public class Test1 { public static void main(String[] args) { // File file = new File("a.txt"); File file = new File("E:\\Users\\Administrator\\eclipse-workspace\\Day22_CharIO\\b.txt"); System.out.println("是否为文件:" + file.isFile()); System.out.println("是否为目录:" + file.isDirectory()); // 目录就是文件夹 System.out.println("是否为可读:" + file.canRead()); System.out.println("是否为可写:" + file.canWrite()); System.out.println("是否为隐藏:" + file.isHidden()); System.out.println("获取绝对路径:" + file.getAbsolutePath()); System.out.println("获取相对路径:" + file.getPath()); System.out.println("获取文件名:" + file.getName()); System.out.println("获取父级目录:" + file.getParentFile()); System.out.println("获取文件长度:" + file.length()); System.out.println("文件是否存在:" + file.exists()); System.out.println("最后一次修改时间:" + file.lastModified()); Date date = new Date(file.lastModified()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(date)); //System.out.println("重命名:" + file.renameTo(new File("b.txt"))); System.out.println("删除文件或删除空目录:"+file.delete()); } }
//File类的应用: //创建指定目录下的文件; 如果上一级目录不存在,则先创建上一级目录 //分析:先获取父级目录,如果父级目录不存在,则创建; 然后再创建子文件 public class Test2 { public static void main(String[] args) throws IOException { File file = new File("a/b/a.txt"); //获取父级目录 File parent = file.getParentFile(); if(parent!=null&&!parent.exists()) { if(parent.mkdirs()) { System.out.println("创建父级目录成立"); } } if(!file.exists()){ if(file.createNewFile()) { System.out.println("创建文件成功"); } } } }
//案例:在指定的a目录下,查找当前层txt为后缀的文件 //分析:1.后缀为txt;2.是文件 //具体操作:实例化a目录的对象;取出下面的文件和目录;再进行判断 public class Test3 { public static void main(String[] args) { File file = new File("a"); File[] files = file.listFiles(); //获取指定目录的所有文件,存到File数组中 //遍历数组 if(files!=null) { for(File f:files) { if(f.isFile()&&f.getName().endsWith(".txt")){ System.out.println(f); } } } } }
//扩展:如果需要找多层的txt //递归,往往就用在File中 //概述: 自己调自己,且需要退出的出口; //回顾说明: 如果能用其他方式,尽量不要用递归;两个弊端:1.效率低 2.容易死递归 //使用递归条件: //1.定义一个方法,找出有规律的数列 //2.要有退出的出口--文件夹中没有目录了 public class Test4 { public static void main(String[] args) { f(new File("a")); } private static void f(File file) { File[] files = file.listFiles(); //获取指定目录的所有文件,存到File数组中 //遍历数组 if(files!=null) { for(File f:files) { if(f.isFile()&&f.getName().endsWith(".txt")){ System.out.println(f); }else if(f.isDirectory()) { f(f); //是目录,则递归调自己 //a/b } } } } }
(=-=!小白我电脑最近有点恰不消了,跑三台虚拟机一卡一卡的,上礼拜刚加装完内存条感觉没啥用,这礼拜准备把机械硬盘换成固态硬盘,工欲善其事必先利其器,大数据的硬件环境得先处理好,不然一个VM就能让你挂在起跑线!!!)