1.IO系统读写文件工具类


1、文本文件读写工具类



[java]  view plain copy


1. <span style="font-size:16px;">package mine.util;  
2.   
3. import java.io.BufferedReader;  
4. import java.io.BufferedWriter;  
5. import java.io.FileReader;  
6. import java.io.FileWriter;  
7. import java.io.IOException;  
8.   
9. /**
10.  * 此工具类用于文本文件的读写
11.  * 
12.  * @author Touch
13.  */  
14. public class TextFile {  
15. // 读取指定路径文本文件  
16. public static String read(String filePath) {  
17. new StringBuilder();  
18. null;  
19. try {  
20. new BufferedReader(new FileReader(filePath));  
21.             String s;  
22. try {  
23. while ((s = in.readLine()) != null)  
24. '\n');  
25. finally {  
26.                 in.close();  
27.             }  
28. catch (IOException e) {  
29. // TODO Auto-generated catch block  
30.             e.printStackTrace();  
31.         }  
32. return str.toString();  
33.     }  
34.   
35. // 写入指定的文本文件,append为true表示追加,false表示重头开始写,  
36. //text是要写入的文本字符串,text为null时直接返回  
37. public static void write(String filePath, boolean append, String text) {  
38. if (text == null)  
39. return;  
40. try {  
41. new BufferedWriter(new FileWriter(filePath,  
42.                     append));  
43. try {  
44.                 out.write(text);  
45. finally {  
46.                 out.close();  
47.             }  
48. catch (IOException e) {  
49. // TODO Auto-generated catch block  
50.             e.printStackTrace();  
51.         }  
52.     }  
53. }  
54. </span>


 



[java]  view plain copy


1. <span style="font-size:16px;">package mine.util;  
2.   
3. public class TestTextFile {  
4. public static void main(String[] args) {  
5. "file/textfile.txt", false,  
6. "这是一个文本文件的读写测试\nTouch\n刘海房\n男\n");  
7. "file/textfile.txt", true, "武汉工业学院\n软件工程");  
8. "file/textfile.txt"));  
9.     }  
10. }  
11. </span>



 

2、二进制文件读写工具类



[java]  view plain copy



    1. <span style="font-size:16px;">package mine.util;  
    2.   
    3. import java.io.BufferedInputStream;  
    4. import java.io.BufferedOutputStream;  
    5. import java.io.FileInputStream;  
    6. import java.io.FileOutputStream;  
    7. import java.io.IOException;  
    8.   
    9. /**
    10.  * 此工具类用于二进制文件的读写
    11.  * 
    12.  * @author Touch
    13.  */  
    14. public class BinaryFile {  
    15. // 把二进制文件读入字节数组,如果没有内容,字节数组为null  
    16. public static byte[] read(String filePath) {  
    17. byte[] data = null;  
    18. try {  
    19. new BufferedInputStream(  
    20. new FileInputStream(filePath));  
    21. try {  
    22. new byte[in.available()];  
    23.                 in.read(data);  
    24. finally {  
    25.                 in.close();  
    26.             }  
    27. catch (IOException e) {  
    28.             e.printStackTrace();  
    29.         }  
    30. return data;  
    31.     }  
    32.   
    33. // 把字节数组为写入二进制文件,数组为null时直接返回  
    34. public static void write(String filePath, byte[] data) {  
    35. if (data == null)  
    36. return;  
    37. try {  
    38. new BufferedOutputStream(  
    39. new FileOutputStream(filePath));  
    40. try {  
    41.                 out.write(data);  
    42. finally {  
    43.                 out.close();  
    44.             }  
    45. catch (IOException e) {  
    46.             e.printStackTrace();  
    47.         }  
    48.     }  
    49. }  
    50. </span>




     



    [java]  view plain copy



    1. <span style="font-size:16px;">package mine.util;  
    2.   
    3. import java.util.Arrays;  
    4.   
    5. public class TestBinaryFile {  
    6. public static void main(String[] args) {  
    7. "file/binaryfile.dat", new byte[] { 1, 2, 3, 4, 5, 6,  
    8. 7, 8, 9, 10, 'a', 'b', 'c' });  
    9. byte[] data = BinaryFile.read("file/binaryfile.dat");  
    10.         System.out.println(Arrays.toString(data));  
    11.     }  
    12. }  
    13. </span>




     

    3、对象读写工具类(有问题,在读取多个对象时有问题,怎样把一个对象文件中的所有对象读出来?)



    [java]  view plain copy



      1. <span style="font-size:16px;">package mine.util;  
      2.   
      3. import java.io.FileInputStream;  
      4. import java.io.FileOutputStream;  
      5. import java.io.IOException;  
      6. import java.io.ObjectInputStream;  
      7. import java.io.ObjectOutputStream;  
      8.   
      9. /**
      10.  * 此类用于对象的读写
      11.  * 
      12.  * @author Touch
      13.  */  
      14. public class ObjectFile {  
      15. // 把一个对象写入文件,isAppend为true表示追加方式写,false表示重新写  
      16. public static void write(String filePath, Object o, boolean isAppend) {  
      17. if (o == null)  
      18. return;  
      19. try {  
      20. new ObjectOutputStream(  
      21. new FileOutputStream(filePath, isAppend));  
      22. try {  
      23.                 out.writeObject(o);  
      24. finally {  
      25.                 out.close();  
      26.             }  
      27. catch (IOException e) {  
      28.             e.printStackTrace();  
      29.         }  
      30.     }  
      31.   
      32. // 把一个对象数组写入文件,isAppend为true表示追加方式写,false表示重新写  
      33. public static void write(String filePath, Object[] objects, boolean isAppend) {  
      34. if (objects == null)  
      35. return;  
      36. try {  
      37. new ObjectOutputStream(  
      38. new FileOutputStream(filePath, isAppend));  
      39. try {  
      40. for (Object o : objects)  
      41.                     out.writeObject(o);  
      42. finally {  
      43.                 out.close();  
      44.             }  
      45. catch (IOException e) {  
      46.             e.printStackTrace();  
      47.         }  
      48.     }  
      49.   
      50. // 读取对象,返回一个对象  
      51. public static Object read(String filePath) {  
      52. null;  
      53. try {  
      54. new ObjectInputStream(new FileInputStream(  
      55.                     filePath));  
      56. try {  
      57.                 o = in.readObject();  
      58. finally {  
      59.                 in.close();  
      60.             }  
      61. catch (Exception e) {  
      62.             e.printStackTrace();  
      63.         }  
      64. return o;  
      65.     }  
      66.   
      67. // 读取对象,返回一个对象数组,count表示要读的对象的个数  
      68. public static Object[] read(String filePath, int count) {  
      69. new Object[count];  
      70. try {  
      71. new ObjectInputStream(new FileInputStream(  
      72.                     filePath));  
      73. try {  
      74. for (int i = 0; i < count; i++) {  
      75. //第二次调用in.readObject()就抛出异常,这是为什么?  
      76.                     objects[i] = in.readObject();  
      77.                 }  
      78. finally {  
      79.                 in.close();  
      80.             }  
      81. catch (Exception e) {  
      82.             e.printStackTrace();  
      83.         }  
      84. return objects;  
      85.     }  
      86. }  
      87. </span>



       



      [java]  view plain copy



        1. <span style="font-size:16px;">package mine.util;  
        2.   
        3. import java.io.Serializable;  
        4.   
        5. public class TestObjectFile {  
        6. public static void main(String[] args) {  
        7. "file/object1", new Person(), false);  
        8. "file/object1", new Person(), true);  
        9. "file/object1", new Person[] { new Person("Touch", 1),  
        10. new Person("Rainbow", 0), new Person() }, true);  
        11. for (Object o : ObjectFile.read("file/object1", 5))  
        12.             ((Person) o).display();  
        13.     }  
        14. }  
        15.   
        16. class Person implements Serializable {  
        17. private String name = "刘海房";  
        18. private int sex = 0;  
        19.   
        20. int sex) {  
        21. this.name = name;  
        22. this.sex = sex;  
        23.     }  
        24.   
        25.     Person() {  
        26.     }  
        27.   
        28. void display() {  
        29. "my name is :" + name);  
        30. 0) ? "男" : "女";  
        31. "性别:" + s);  
        32.     }  
        33. }</span>




        4、对象读写工具类(解决了3中的问题,能够写入及读取多个对象)

                  3中到底问题出在哪呢?先来看一段ObjectOutputStream构造方法的源代码,此源代码来自jdk1.6版。



        [java]  view plain copy



          1. <span style="font-size:16px;">    public ObjectOutputStream(OutputStream out) throws IOException {  
          2.     verifySubclass();  
          3. new BlockDataOutputStream(out);  
          4. new HandleTable(10, (float) 3.00);  
          5. new ReplaceTable(10, (float) 3.00);  
          6. false;  
          7. "font-size:16px;"><span style="color:#ff0000;">writeStreamHeader();  
          8. </span> bout.setBlockDataMode(true);  
          9. if (extendedDebugInfo) {  
          10. new DebugTraceInfoStack();  
          11. else {  
          12. null;  
          13.         }     
          14.     }</span>




          这段代码中我们只需要关注writeStreamHeader();方法,这个方法在源代码中的解释是



          [java]  view plain copy



          1. <span style="font-size:16px;"> /**
          2.      * The writeStreamHeader method is provided so subclasses can append or
          3.      * prepend their own header to the stream.  It writes the magic number and
          4.      * version to the stream.
          5.      *
          6.      * @throws  IOException if I/O errors occur while writing to the underlying
          7.      *      stream
          8.      */</span>



          也就是说我们打开(new)一个ObjectOutputStream的时候,这个ObjectOutputStream流中就已经被写入了一些信息,这些信息会写入到我们的文件中。在第一次写入文件时,这些头部信息时需要的,因为ObjectInputStream读的时候会帮我们过滤掉。但是当我们追加写入一个文件时,这些头部信息也会写入文件中,读取的时候只会把文件第一次出现的头部信息过滤掉,并不会把文件中间的头部信息也过滤掉,这就是问题的根源所在。

          lichong_87提到的

                一、可以在每次写入的时候把文件中所有对象读出来,然后重新写入,这种方法效率比较低。

          writeStreamHeader();方法中写入的,所以我们可以通过继承ObjectOutputStream来覆盖这个方法,如果不是第一次写入文件,这个方法什么也不做。

               下面是第二种解决方案的源代码及测试



          [java]  view plain copy



          1. <span style="font-size:16px;">package mine.util.io;  
          2.   
          3. import java.io.File;  
          4. import java.io.IOException;  
          5. import java.io.ObjectOutputStream;  
          6. import java.io.OutputStream;  
          7.   
          8. /**
          9.  * 此类继承ObjectOutputStream,重写writeStreamHeader()方法,以实现追加写入时去掉头部信息
          10.  */  
          11. public class MyObjectOutputStream extends ObjectOutputStream {  
          12. private static File f;  
          13.   
          14. // writeStreamHeader()方法是在ObjectOutputStream的构造方法里调用的  
          15. // 由于覆盖后的writeStreamHeader()方法用到了f。如果直接用此构造方法创建  
          16. // 一个MyObjectOutputStream对象,那么writeStreamHeader()中的f是空指针  
          17. // 因为f还没有初始化。所以这里采用单态模式  
          18. private MyObjectOutputStream(OutputStream out, File f) throws IOException,  
          19.             SecurityException {  
          20. super(out);  
          21.     }  
          22.   
          23. // 返回一个MyObjectOutputStream对象,这里保证了new MyObjectOutputStream(out, f)  
          24. // 之前f已经指向一个File对象  
          25. public static MyObjectOutputStream newInstance(File file, OutputStream out)  
          26. throws IOException {  
          27. // 本方法最重要的地方:构建文件对象,两个引用指向同一个文件对象  
          28. return new MyObjectOutputStream(out, f);  
          29.     }  
          30.   
          31. @Override  
          32. protected void writeStreamHeader() throws IOException {  
          33. // 文件不存在或文件为空,此时是第一次写入文件,所以要把头部信息写入。  
          34. if (!f.exists() || (f.exists() && f.length() == 0)) {  
          35. super.writeStreamHeader();  
          36. else {  
          37. // 不需要做任何事情  
          38.         }  
          39.     }  
          40. }  
          41. </span>






          [java]  view plain copy



            1. <span style="font-size:16px;">package mine.util.io;  
            2.   
            3. import java.io.File;  
            4. import java.io.FileInputStream;  
            5. import java.io.FileOutputStream;  
            6. import java.io.IOException;  
            7. import java.io.ObjectInputStream;  
            8.   
            9. /**
            10.  * 此类用于对象的读写
            11.  * 
            12.  * @author Touch
            13.  */  
            14. public class ObjectFile {  
            15. // 把一个对象写入文件,isAppend为true表示追加方式写,false表示重新写  
            16. public static void write(String filePath, Object o, boolean isAppend) {  
            17. if (o == null)  
            18. return;  
            19. try {  
            20. new File(filePath);  
            21.             MyObjectOutputStream out = MyObjectOutputStream.newInstance(f,  
            22. new FileOutputStream(f, isAppend));  
            23. try {  
            24.                 out.writeObject(o);  
            25. finally {  
            26.                 out.close();  
            27.             }  
            28. catch (IOException e) {  
            29.             e.printStackTrace();  
            30.         }  
            31.     }  
            32.   
            33. // 把一个对象数组写入文件,isAppend为true表示追加方式写,false表示重新写  
            34. public static void write(String filePath, Object[] objects, boolean isAppend) {  
            35. if (objects == null)  
            36. return;  
            37. try {  
            38. new File(filePath);  
            39.             MyObjectOutputStream out = MyObjectOutputStream.newInstance(f,  
            40. new FileOutputStream(f, isAppend));  
            41. try {  
            42. for (Object o : objects)  
            43.                     out.writeObject(o);  
            44. finally {  
            45.                 out.close();  
            46.             }  
            47. catch (IOException e) {  
            48.             e.printStackTrace();  
            49.         }  
            50.     }  
            51.   
            52. // 读取对象,返回一个对象  
            53. public static Object read(String filePath) {  
            54. null;  
            55. try {  
            56. new ObjectInputStream(new FileInputStream(  
            57.                     filePath));  
            58. try {  
            59.                 o = in.readObject();  
            60. finally {  
            61.                 in.close();  
            62.             }  
            63. catch (Exception e) {  
            64.             e.printStackTrace();  
            65.         }  
            66. return o;  
            67.     }  
            68.   
            69. // 读取对象,返回一个对象数组,count表示要读的对象的个数  
            70. public static Object[] read(String filePath, int count) {  
            71. new Object[count];  
            72. try {  
            73. new ObjectInputStream(new FileInputStream(  
            74.                     filePath));  
            75. try {  
            76. for (int i = 0; i < count; i++) {  
            77.                       
            78.                     objects[i] = in.readObject();  
            79.                 }  
            80. finally {  
            81.                 in.close();  
            82.             }  
            83. catch (Exception e) {  
            84.             e.printStackTrace();  
            85.         }  
            86. return objects;  
            87.     }  
            88. }  
            89. </span>



            [java]  view plain copy



            1. <span style="font-size:16px;">package mine.util.io;  
            2.   
            3. import java.io.Serializable;  
            4.   
            5. public class TestObjectFile {  
            6. public static void main(String[] args) {  
            7. "file/t.dat", new Person(), false);  
            8. "file/t.dat", new Person(), true);  
            9. "file/t.dat", new Person[] { new Person("Touch", 1),  
            10. new Person("Rainbow", 0), new Person() }, true);  
            11. for (Object o : ObjectFile.read("file/t.dat", 5))  
            12.             ((Person) o).display();  
            13.     }  
            14. }  
            15.   
            16. class Person implements Serializable {  
            17. private static final long serialVersionUID = 1L;  
            18. private String name = "刘海房";  
            19. private int sex = 0;  
            20.   
            21. int sex) {  
            22. this.name = name;  
            23. this.sex = sex;  
            24.     }  
            25.   
            26.     Person() {  
            27.     }  
            28.   
            29. void display() {  
            30. "my name is :" + name);  
            31. 0) ? "男" : "女";  
            32. "性别:" + s);  
            33.     }  
            34. }</span>




            运行结果:

            my name is :刘海房
            性别:男
            my name is :刘海房
            性别:男
            my name is :Touch
            性别:女
            my name is :Rainbow
            性别:男
            my name is :刘海房
            性别:男


            2.IO系统File类及文件搜索工具类


            1、先看一个File类的简单的例子

            [java]  view plain copy



              1. <span style="font-size:16px;">package test;  
              2.   
              3. import java.io.File;  
              4. import java.io.FilenameFilter;  
              5. import java.util.Arrays;  
              6. import java.util.Scanner;  
              7. import java.util.regex.Pattern;  
              8.   
              9. /**
              10.  * File代表文件和目录,静态域有:与系统有关的路径分隔符、与系统有关的默认名称分隔符。
              11.  * 主要操作有:创建文件或目录、删除文件、给文件设定属性、返回指定目录下的文件列表、
              12.  *          返回过滤后的文件列表、 检测文件是否存在、是否隐藏、是否是目录还是文件、
              13.  *          返回文件名称和路径
              14.  * 
              15.  * @author Touch
              16.  *
              17.  */  
              18. public class FileDemo {  
              19. /*
              20.      * 查找指定路径下的匹配regex的文件
              21.      */  
              22. public String[] find(String path, final String regex) {  
              23. new File(path);  
              24. //匿名内部类  
              25. return file.list(new FilenameFilter() {  
              26. private Pattern pattern = Pattern.compile(regex);  
              27. @Override  
              28. public boolean accept(File dir, String name) {  
              29. // TODO Auto-generated method stub  
              30. return pattern.matcher(name).matches();  
              31.             }  
              32.         });  
              33.     }  
              34.   
              35. public static void main(String[] args) {  
              36. null;  
              37. null;  
              38. null;  
              39. int choice = 1;  
              40. new Scanner(System.in);  
              41. "please input the file path:");  
              42.         path = scanner.next();  
              43. "please input key:");  
              44.         key = scanner.next();  
              45. "choise:\n0:匹配以" + key + "为后缀的文件\n1:匹配包含" + key  
              46. "的文件");  
              47. if ((choice = scanner.nextInt()) == 0)  
              48. ".*\\." + key;  
              49. else  
              50. ".*" + key + ".*";  
              51.         String[] list;  
              52. new FileDemo().find(path, regex);  
              53.         System.out.println(Arrays.deepToString(list));  
              54. //返回指定路径下的目录列表  
              55. new File(path).listFiles();  
              56. for (File file : fileList) {  
              57. if (file.isDirectory()) {  
              58. new FileDemo().find(file.getPath(), regex);  
              59.                 System.out.println(Arrays.deepToString(list));  
              60.             }  
              61.         }  
              62.     }  
              63.   
              64. }  
              65. </span>




              2、看完这个例子,是不是可以写个工具类呢,用于搜索指定路径下的所有文件或者目录,当然也可以输入正则表达式,这样就可以筛选出我们想要的文件(如有时候我们只需要.java文件或者.txt文件)




              [java]  view plain copy



                1. <span style="font-size:16px;">package mine.util;  
                2.   
                3. import java.io.File;  
                4. import java.util.ArrayList;  
                5. import java.util.List;  
                6.   
                7. /**
                8.  * FileDirectory类用于查找指定根目录下的所有文件和目录 可以通过正则表达式对要查找的 文件及目录进行筛选
                9.  * 
                10.  * @author Touch
                11.  */  
                12. public final class SearchFile {  
                13. // 存放文件  
                14. private List<File> fileList = new ArrayList<File>();  
                15. // 存放目录  
                16. private List<File> directoryList = new ArrayList<File>();  
                17. // 存放文件和目录  
                18. private List<File> list = new ArrayList<File>();  
                19. private File file;// 目录  
                20. private String regex;// 正则表达式  
                21.   
                22. public SearchFile(String path) {  
                23. new File(path);  
                24. this.regex = ".*";  
                25.     }  
                26.   
                27. public SearchFile(File file) {  
                28. this.file = file;  
                29. this.regex = ".*";  
                30.     }  
                31.   
                32. public SearchFile(String path, String regex) {  
                33. new File(path);  
                34. this.regex = regex;  
                35.     }  
                36.   
                37. public SearchFile(File file, String regex) {  
                38. this.file = file;  
                39. this.regex = regex;  
                40.     }  
                41.   
                42. // 返回当前目录下的所有文件及子目录  
                43. public List<File> files() {  
                44.         File[] files = file.listFiles();  
                45. new ArrayList<File>();  
                46. for (File f : files)  
                47. if (f.getName().matches(regex))  
                48.                 list.add(f);  
                49. return list;  
                50.     }  
                51.   
                52. // 返回该根目录下的所有文件  
                53. public List<File> allFiles() {  
                54. if (list.isEmpty())  
                55.             search(file);  
                56. return fileList;  
                57.     }  
                58.   
                59. // 返回该根目录下的所有子目录  
                60. public List<File> allDirectory() {  
                61. if (list.isEmpty())  
                62.             search(file);  
                63. return directoryList;  
                64.     }  
                65.   
                66. // 返回该根目录下的所有文件及子目录  
                67. public List<File> allFilesAndDirectory() {  
                68. if (list.isEmpty())  
                69.             search(file);  
                70. return list;  
                71.     }  
                72.   
                73. // 递归搜索当前目录下的所有文件及目录  
                74. private void search(File file) {  
                75.         File[] files = file.listFiles();  
                76. if (files == null || files.length == 0)  
                77. return;  
                78. for (File f : files) {  
                79. if (f.getName().matches(regex))  
                80.                 list.add(f);  
                81. if (f.isFile() && f.getName().matches(regex))  
                82.                 fileList.add(f);  
                83. else {  
                84. if (f.getName().matches(regex))  
                85.                     directoryList.add(f);  
                86.                 search(f);  
                87.             }  
                88.         }  
                89.     }  
                90. }  
                91. </span>



                3、测试



                [java]  view plain copy



                  1. <span style="font-size:16px;">package mine.util;  
                  2.   
                  3. import java.io.File;  
                  4. import java.util.List;  
                  5.   
                  6. public class TestSearchFile {  
                  7. public static void main(String[] args) {  
                  8. "-------- 指定目录中所有文件及子目录-------");  
                  9. new SearchFile(  
                  10. "G:/java/workspace/test/file").files();  
                  11. for (File file : list)  
                  12.             System.out.println(file.getName());  
                  13. "--------指定目录中以txt为后缀的文件------");  
                  14. new SearchFile("G:/java/workspace/test/file",  
                  15. ".*\\.txt").files();  
                  16. for (File file : list)  
                  17.             System.out.println(file.getName());  
                  18. "--------以该目录为根目录的所有文件及子目录--");  
                  19. new SearchFile("G:/java/workspace/test")  
                  20.                 .allFilesAndDirectory();  
                  21. for (File file : list)  
                  22.             System.out.println(file.getName());  
                  23.     }  
                  24. }  
                  25. </span>




                  4、结果:

                  -------- 指定目录中所有文件及子目录-------
                  aa.data
                  bb.dat
                  object
                  test.txt
                  test1.txt
                  test2.txt
                  test3.txt
                  test4.txt
                  test5
                  --------指定目录中以txt为后缀的文件------
                  test.txt
                  test1.txt
                  test2.txt
                  test3.txt
                  test4.txt
                  --------以该目录为根目录的所有文件及子目录--
                  .classpath
                  .project
                  .settings
                  org.eclipse.jdt.core.prefs
                  bin
                  http
                  PassWord.class
                  Test.class
                  mine
                  util
                  SearchFile.class
                  TestSearchFile.class
                  test
                  A.class
                  ArraysDemo.class
                  B.class
                  ByteArrayInputStreamDemo.class
                  DataInputStreamAndByteArrayInputStreamDemo.class
                  DataInputStreamDemo.class
                  DeepCloneDemo.class
                  FileDemo$1.class
                  FileDemo.class
                  FileInputStreamDemo.class