Java笔记(七)
File类:
1 import java.io.File; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 //将a.txt封装成file对象。可以将已有的和未出现的文件或者文件夹封装成对象 7 File f1 = new File("a.txt"); 8 9 //左边参数是父目录,右边是文件名 10 File f2 = new File("C:", "demo.txt"); 11 12 File d = new File("C:\\abc"); 13 File f3 = new File(d, "c.txt"); 14 15 //因为\\是windows下的分割符,而File.separator是可以跨平台的 16 ile f4 = new File("C:" + File.separator + "abc" + File.separator + "c.txt");17 18 } 19 }
File类常见方法:
(1)创建:boolean createNewFile(); 在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立,就会创建文件,而且文件已经存在,会覆盖。
boolean mkdir(); 创建文件夹。
boolean mkdirs(); 创建多级文件夹。
(2)删除:boolean delete(); 删除失败返回false。
boolean deleteOnExit(); 在程序退出时删除指定文件。
(3)判断:boolean canExecute(); 测试应用程序是否可以执行此抽象路径名表示的文件。
boolean exists(); 文件是否存在。
isFile();
isDirectory();
isHidden();
isAbsolute(); 测试此抽象路径名是否为绝对路径名。
在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在,通过exists判断。
(4)获取信息:
getName(); getPath(); getParent(); getAbsolutePath(); long lastModified(); 文件最后一次被修改的时间 long length();
输出C盘下所有文件和文件夹的名字:
1 import java.io.File; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 File f = new File("C:\\"); 7 String[] names = f.list(); 8 for(String name : names){ 9 System.out.println(name); 10 } 11 } 12 }
输出G盘中后缀名为.txt的文件名:
1 import java.io.File; 2 import java.io.FilenameFilter; 3 import java.io.IOException; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException{ 7 // File f = new File("G:\\"); 8 // String[] arr = f.list(new FilenameFilter(){ 9 // public boolean accept(File dir, String name){ 10 // return name.endsWith(".txt"); 11 // } 12 // }); 13 // for(String name : arr){ 14 // System.out.println(name); 15 // } 16 17 File f = new File("G:\\"); 18 File[] files = f.listFiles(new FilenameFilter() { 19 public boolean accept(File f, String name) { 20 return name.endsWith(".txt"); 21 } 22 }); 23 for(File file : files){ 24 System.out.println(file.getName()); 25 } 26 } 27 }
列出指定目录下文件或文件夹,包含目录中的内容。也就是列出指定目录下所有内容(递归):
1 import java.io.File; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 File dir = new File("F:\\text"); 7 showDir(dir); 8 } 9 public static void showDir(File dir){ 10 System.out.println(dir); 11 File[] files = dir.listFiles(); 12 for(File f : files){ 13 if(f.isDirectory()){ 14 showDir(f); 15 } 16 else{ 17 System.out.println(f); 18 } 19 } 20 } 21 }
加入层次效果:
1 import java.io.File; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 File dir = new File("F:\\text"); 7 showDir(dir, 0); 8 } 9 public static String getLevel(int level){ 10 StringBuilder sb = new StringBuilder(); 11 for(int i = 0; i < level; i++){ 12 sb.append(" "); 13 } 14 return sb.toString(); 15 } 16 public static void showDir(File dir, int level){ 17 System.out.println(getLevel(level) + dir); 18 level++; 19 File[] files = dir.listFiles(); 20 for(File f : files){ 21 if(f.isDirectory()){ 22 showDir(f, level); 23 } 24 else{ 25 System.out.println(getLevel(level) + f); 26 } 27 } 28 } 29 }
删除一个带内容的目录。删除原理:在windows中,删除目录从里往外删除。所以就需要递归:
1 import java.io.File; 2 3 public class Demo{ 4 public static void main(String[] args){ 5 File dir = new File("F:\\testdir"); 6 removeDir(dir); 7 } 8 public static void removeDir(File dir){ 9 File[] files = dir.listFiles(); 10 for(File file : files){ 11 if(file.isDirectory()){ 12 removeDir(file); 13 } 14 else{ 15 System.out.println(file.toString() + ":-file-" + file.delete()); 16 } 17 } 18 System.out.println(dir + "::dir::" + dir.delete()); 19 } 20 }
将一个指定目录下的Java文件的绝对路径,存储到一个文本文件中。建立一个Java列表文件。
1 import java.io.BufferedWriter; 2 import java.io.File; 3 import java.io.FileWriter; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 public class Demo{ 9 public static void main(String[] args){ 10 File dir = new File("C:\\Users\\ZTQ\\Desktop\\JavaText"); 11 List<File> list = new ArrayList<File>(); 12 fileToList(dir, list); 13 File file = new File(dir, "javalist.txt"); 14 writeToFile(list, file.toString()); 15 } 16 //目录中的.java文件写入到list中 17 public static void fileToList(File dir, List<File> list){ 18 File[] files = dir.listFiles(); 19 for(File f : files){ 20 if(f.isDirectory()){ 21 fileToList(f, list); 22 } 23 else{ 24 list.add(f); 25 } 26 } 27 } 28 //list写入到文件中 29 public static void writeToFile(List<File> list, String path){ 30 BufferedWriter bufw = null; 31 try{ 32 bufw = new BufferedWriter(new FileWriter(path)); 33 for(File f : list){ 34 String p = f.getAbsolutePath(); 35 bufw.write(p); 36 bufw.newLine(); 37 bufw.flush(); 38 } 39 }catch(IOException e){ 40 throw new RuntimeException(e.toString()); 41 }finally{ 42 if(bufw != null){ 43 try{ 44 bufw.close(); 45 }catch(IOException e){ 46 throw new RuntimeException(e.toString()); 47 } 48 } 49 } 50 } 51 }
Properties是hashtable的子类。它具备map集合的特点,而且它里面存储的键值对都是字符串。是集合中与IO技术相结合的集合容器。对象特点:可以用于键值对形式的配置文件。
1 import java.util.Properties; 2 import java.util.Set; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 setAndGet(); 7 } 8 public static void setAndGet(){ 9 Properties prop = new Properties(); 10 prop.setProperty("zhangsan", "30"); 11 prop.setProperty("lisi", "40"); 12 13 String value = prop.getProperty("lisi"); 14 System.out.println(value); 15 16 prop.setProperty("lisi", "50"); 17 Set<String> names = prop.stringPropertyNames(); 18 for(String s : names){ 19 System.out.println(s + ":" + prop.getProperty(s)); 20 } 21 } 22 }
将info.txt中键值数据存到集合中进行操作:
(1)用一个流和info.txt文件关联
(2)读取一行数据,将该行数据用“=”进行切割
(3)“=”左边作为键,右边作为值,存入到Properties集合中即可。
1 import java.io.BufferedReader; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.util.Properties; 7 8 public class Demo{ 9 public static void main(String[] args)throws IOException{ 10 method_02(); 11 } 12 public static void method_01() throws IOException{ 13 BufferedReader bufr = new BufferedReader(new FileReader("F:\\demo.txt")); 14 String line = null; 15 Properties prop = new Properties(); 16 while((line = bufr.readLine()) != null){ 17 String[] arr = line.split("="); 18 prop.setProperty(arr[0], arr[1]); 19 } 20 bufr.close(); 21 System.out.println(prop); 22 } 23 public static void method_02()throws IOException{ 24 FileInputStream fis = new FileInputStream("F:\\demo.txt"); 25 Properties prop = new Properties(); 26 //将流中的数据加载进集合 27 prop.load(fis); 28 29 // prop.setProperty("wangwu", "39"); 只能设置内存中的内容,而文件中的内容不改变 30 FileOutputStream fos = new FileOutputStream("F:\\demo.txt"); 31 prop.store(fos, "haha"); //第二个参数为注释信息 32 33 prop.list(System.out); 34 fis.close(); 35 fos.close(); 36 } 37 38 }
记录应用程序运行次数,如果使用次数已到,给出注册提示:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.util.Properties; 6 7 public class Demo{ 8 public static void main(String[] args)throws IOException{ 9 Properties prop = new Properties(); 10 11 File file = new File("F:\\count.ini"); 12 if(!file.exists()) 13 file.createNewFile(); 14 15 FileInputStream fis = new FileInputStream(file); 16 17 prop.load(fis); 18 19 int count = 0; 20 String value = prop.getProperty("times"); 21 22 if(value != null){ 23 count = Integer.parseInt(value); 24 if(count >= 5){ 25 System.out.println("使用次数已到,请充值!"); 26 return; 27 } 28 } 29 count++; 30 31 prop.setProperty("times", count + ""); 32 33 FileOutputStream fos = new FileOutputStream(file); 34 prop.store(fos, ""); 35 36 fis.close(); 37 fos.close(); 38 } 39 }
打印流:该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流 PrintStream:
构造函数可以接收的参数类型:
(1)file对象。File
(2)字符串路径。String
(3)字节输出流。OutputStream
字符打印流 PrintWriter:
构造函数可以接收的参数类型:
(1)file对象。File
(2)字符串路径。String
(3)字节输出流。OutputStream
(4)字符输出流。Writer
1 import java.io.BufferedReader; 2 import java.io.FileWriter; 3 import java.io.IOException; 4 import java.io.InputStreamReader; 5 import java.io.PrintWriter; 6 7 public class Demo{ 8 public static void main(String[] args)throws IOException{ 9 BufferedReader bufr = 10 new BufferedReader(new InputStreamReader(System.in)); 11 PrintWriter out = new PrintWriter(new FileWriter("F:\\demo.txt"), true); //第二个参数为true,则println,printf或format方法将刷新输出缓冲区 12 13 String line = null; 14 while((line = bufr.readLine()) != null){ 15 if("over".equals(line)) break; 16 out.println(line.toUpperCase()); 17 } 18 out.close(); 19 bufr.close(); 20 } 21 }
合并流SequenceInputStream:
1 import java.io.FileInputStream; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 import java.io.SequenceInputStream; 5 import java.util.Enumeration; 6 import java.util.Vector; 7 8 public class Demo{ 9 public static void main(String[] args)throws IOException{ 10 Vector<FileInputStream> v = new Vector<FileInputStream>(); 11 v.add(new FileInputStream("F:\\1.txt")); 12 v.add(new FileInputStream("F:\\2.txt")); 13 v.add(new FileInputStream("F:\\3.txt")); 14 15 Enumeration<FileInputStream> en = v.elements(); 16 SequenceInputStream sis = new SequenceInputStream(en); 17 FileOutputStream fos = new FileOutputStream("F:\\4.txt"); 18 byte[] buf = new byte[1024]; 19 int len = 0; 20 while((len = sis.read(buf)) != -1){ 21 fos.write(buf, 0, len); 22 } 23 fos.close(); 24 sis.close(); 25 } 26 }
切割文件:
1 import java.io.FileInputStream; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 import java.io.SequenceInputStream; 5 import java.util.ArrayList; 6 import java.util.Enumeration; 7 import java.util.Iterator; 8 9 public class Demo{ 10 public static void main(String[] args)throws IOException{ 11 splitFile(); 12 merge(); 13 } 14 public static void splitFile() throws IOException{ 15 FileInputStream fis = new FileInputStream("F:\\pic.jpg"); 16 FileOutputStream fos = null; 17 18 byte[] buf = new byte[1024]; 19 int len = 0; 20 int count = 1; 21 while((len = fis.read(buf)) != -1){ 22 fos = new FileOutputStream("F:\\" + count++ + ".part"); 23 fos.write(buf, 0, len); 24 fos.close(); 25 } 26 fis.close(); 27 } 28 public static void merge()throws IOException{ 29 ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); 30 for(int i = 1; i <= 4; i++){ 31 al.add(new FileInputStream("F:\\" + i + ".part")); 32 } 33 final Iterator<FileInputStream> it = al.iterator(); 34 Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){ 35 public boolean hasMoreElements() { 36 return it.hasNext(); 37 } 38 public FileInputStream nextElement() { 39 return it.next(); 40 } 41 }; 42 SequenceInputStream sis = new SequenceInputStream(en); 43 FileOutputStream fos = new FileOutputStream("F:\\merge.jpg"); 44 int len = 0; 45 byte[] buf = new byte[1024]; 46 while((len = sis.read(buf)) != -1){ 47 fos.write(buf, 0, len); 48 } 49 fos.close(); 50 sis.close(); 51 } 52 }
对象的序列化:
1 import java.io.FileInputStream; 2 import java.io.FileOutputStream; 3 import java.io.ObjectInputStream; 4 import java.io.ObjectOutputStream; 5 6 public class Demo{ 7 public static void main(String[] args)throws Exception{ 8 writeObj(); 9 readObj(); 10 } 11 public static void readObj()throws Exception{ 12 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("F:\\obj.txt")); 13 Person p = (Person)ois.readObject(); 14 System.out.println(p); 15 ois.close(); 16 } 17 public static void writeObj()throws Exception{ 18 ObjectOutputStream oos = 19 new ObjectOutputStream(new FileOutputStream("F:\\obj.txt")); 20 oos.writeObject(new Person("ztq", 23)); 21 oos.close(); 22 } 23 }
管道流:
管道输入流应该连接到管道输出流,管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从PipedInputStream对象读取,并由其他线程将其写入到对应的PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。
1 import java.io.IOException; 2 import java.io.PipedInputStream; 3 import java.io.PipedOutputStream; 4 5 class Read implements Runnable{ 6 private PipedInputStream in; 7 Read(PipedInputStream in){ 8 this.in = in; 9 } 10 public void run(){ 11 try{ 12 byte[] buf = new byte[1024]; 13 int len = in.read(buf); 14 String s = new String(buf, 0, len); 15 System.out.println(s); 16 in.close(); 17 }catch(IOException e){ 18 throw new RuntimeException("管道读取流失败!"); 19 } 20 } 21 } 22 23 class Write implements Runnable{ 24 private PipedOutputStream out; 25 Write(PipedOutputStream out){ 26 this.out = out; 27 } 28 public void run(){ 29 try{ 30 out.write("piped!~".getBytes()); 31 out.close(); 32 }catch(IOException e){ 33 throw new RuntimeException("管道输入流失败!"); 34 } 35 } 36 } 37 public class Demo{ 38 public static void main(String[] args)throws Exception{ 39 PipedInputStream in = new PipedInputStream(); 40 PipedOutputStream out = new PipedOutputStream(); 41 in.connect(out); 42 new Thread(new Read(in)).start(); 43 new Thread(new Write(out)).start(); 44 } 45 46 }
RandomAccessFile:
该类不算是IO体系中的子类,直接继承的Object。但它却是IO包中的成员,因为它具备读和写功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入输出流。
通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式mode:如r只读,rw读和写等。如果模式为r,不会创建文件,会读取一个已存在的文件,如果文件不存在,则会出现异常。如果模式为rw,操作的文件不存在,会自动创建,如果存在则不会覆盖。
1 import java.io.IOException; 2 import java.io.RandomAccessFile; 3 4 public class Demo{ 5 public static void main(String[] args)throws Exception{ 6 writeFile_2(); 7 readFile(); 8 } 9 public static void readFile() throws IOException{ 10 RandomAccessFile raf = new RandomAccessFile("F:\\ran.txt", "r"); 11 12 //调整对象中的指针 13 raf.seek(8); 14 15 //跳过指定的字节数,只能往后跳 16 //raf.skipBytes(8); 17 18 byte[] buf = new byte[4]; 19 raf.read(buf); 20 String name = new String(buf); 21 int age = raf.readInt(); 22 System.out.println("name = " + name); 23 System.out.println("age = " + age); 24 raf.close(); 25 } 26 public static void writeFile() throws IOException{ 27 RandomAccessFile raf = new RandomAccessFile("F:\\ran.txt", "rw"); 28 raf.write("李四".getBytes()); 29 raf.writeInt(97); 30 raf.write("王五".getBytes()); 31 raf.writeInt(99); 32 raf.close(); 33 } 34 public static void writeFile_2() throws IOException{ 35 RandomAccessFile raf = new RandomAccessFile("F:\\ran.txt", "rw"); 36 raf.seek(8 * 1); 37 raf.write("哈哈".getBytes()); 38 raf.close(); 39 } 40 }
DataStream:
可以用于操作基本数据类型的流对象。
1 import java.io.DataInputStream; 2 import java.io.DataOutputStream; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 public class Demo{ 8 public static void main(String[] args)throws Exception{ 9 writeData(); 10 readData(); 11 } 12 public static void writeData() throws IOException{ 13 DataOutputStream dos = new DataOutputStream(new FileOutputStream("F:\\demo.txt")); 14 dos.writeInt(123); 15 dos.writeBoolean(true); 16 dos.writeDouble(12.34); 17 dos.close(); 18 } 19 public static void readData() throws IOException{ 20 DataInputStream dis = new DataInputStream(new FileInputStream("F:\\demo.txt")); 21 int n1 = dis.readInt(); 22 boolean n2 = dis.readBoolean(); 23 double n3 = dis.readDouble(); 24 System.out.println("n1 = " + n1); 25 System.out.println("n2 = " + n2); 26 System.out.println("n3 = " + n3); 27 dis.close(); 28 } 29 }
ByteArrayStream:
用于操作字节数组的流对象。
ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭。
1 import java.io.ByteArrayInputStream; 2 import java.io.ByteArrayOutputStream; 3 4 public class Demo{ 5 public static void main(String[] args){ 6 //数据源 7 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFG".getBytes()); 8 9 //数据目的 10 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 11 12 int by = 0; 13 while((by = bis.read()) != -1){ 14 bos.write(by); 15 } 16 17 System.out.println(bos.size()); 18 System.out.println(bos.toString()); 19 } 20 21 }
编码:字符串变成字节数组。
解码:字节数组变成字符串。
String-->byte[] str.getBytes();
byte[]-->String new String(byte[]);
有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课成绩),输入的格式,如:zhangsan,30,40,60计算出总成绩,并把学生的信息和计算出的总分数按照高低顺序存放在磁盘文件“stud.txt”中:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileWriter; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.util.Collections; 7 import java.util.Comparator; 8 import java.util.Set; 9 import java.util.TreeSet; 10 11 12 class Student implements Comparable<Student>{ 13 private String name; 14 private int c1, c2, c3; 15 private int sum; 16 17 public Student(String name, int c1, int c2, int c3){ 18 this.name = name; 19 this.c1 = c1; 20 this.c2 = c2; 21 this.c3 = c3; 22 sum = c1 + c2 + c3; 23 } 24 25 public String getName(){ 26 return name; 27 } 28 29 public int getSum(){ 30 return sum; 31 } 32 33 public int hashCode(){ 34 return name.hashCode() + sum * 78; 35 } 36 37 public boolean equals(Object obj){ 38 if(!(obj instanceof Student)) 39 throw new ClassCastException("类型不匹配"); 40 Student s = (Student)obj; 41 return this.name.equals(s.name) && this.sum == s.sum; 42 } 43 44 public int compareTo(Student s) { 45 int num = new Integer(this.sum).compareTo(new Integer(s.sum)); 46 if(num == 0){ 47 return this.name.compareTo(s.name); 48 } 49 return num; 50 } 51 52 public String toString(){ 53 return "Student[ " + name + ", " + c1 + ", " + c2 + ", " + c3 + " ]"; 54 } 55 } 56 57 class StudentInfoTool{ 58 //使用默认比较器的方法 59 public static Set<Student> getStudents() throws IOException{ 60 return getStudents(null); 61 } 62 //使用传入的比较器的方法 63 public static Set<Student> getStudents(Comparator<Student> cmp) throws IOException{ 64 BufferedReader bufr = 65 new BufferedReader(new InputStreamReader(System.in)); 66 String line = null; 67 Set<Student> stus = null; 68 if(cmp == null) 69 stus = new TreeSet<Student>(); 70 else 71 stus = new TreeSet<Student>(cmp); 72 while((line = bufr.readLine()) != null){ 73 if("over".equals(line)) 74 break; 75 String[] arr = line.split(","); 76 Student stu = new Student(arr[0], Integer.parseInt(arr[1]), 77 Integer.parseInt(arr[2]), 78 Integer.parseInt(arr[3])); 79 stus.add(stu); 80 } 81 bufr.close(); 82 return stus; 83 } 84 public static void write2File(Set<Student> stus) throws IOException{ 85 BufferedWriter bufw = new BufferedWriter(new FileWriter("F:\\students.txt")); 86 for(Student stu : stus){ 87 bufw.write(stu.toString()); 88 bufw.write(" " + stu.getSum()); 89 bufw.newLine(); 90 bufw.flush(); 91 } 92 bufw.close(); 93 } 94 } 95 public class Demo{ 96 public static void main(String[] args) throws IOException{ 97 Comparator<Student> cmp = Collections.reverseOrder(); 98 Set<Student> stus = StudentInfoTool.getStudents(cmp); 99 StudentInfoTool.write2File(stus); 100 } 101 }