黑马程序员_IO流2

                                

                                  File类

1、File类

     不属于流对象。作用:将机器上的路径和目录封装成一个File对象,提供了很多的方法和成员变量,让我们操作目录和路径

      目录就是文件夹。路径,指由文件夹组成的到达文件夹的通道。

2、File类的静态成员变量

     一共提供的4个变量,掌握的只有2个,跨平台

    static String separator  结果\ Windows目录分隔符  Linux下 /

    static String pathSeparator 结果 ; Windows下的路径与路径之间的分隔符 Linux :

3、File类的构造方法

    File(String pathname) 将一个字符串的路径,封装成File对象.只复杂把路径封装成对象,至于路径有没有,够造方法不考虑。(参数写到文件夹,写到文件也行)

    File(String parent,String child)传递两个,字符串格式父路径,字符串格式子路径

    File(File parent,String child)传递两个,File类型父路径,字符串格式子路径

4、File类的创建功能     

    boolean createNewFile()创建新文件,创建成功返回true,所创建的文件是File构造方法中封装的文件,文件已经存在,不会创建,只能创建文件 

    boolean mkdir()创建目录,文件夹,创建成功返回true,创建的是File构造方法中封装的路径,目录存在,不在创建了   

    boolean mkdirs()创建多级目录

5、File类的删除方法

    boolean delete()删除File构造方法中封装的路径,成功返回true,不走回收站。删除目录必须保证目录是空的

    void deleteOnExit()延迟删除,等待JVM退出之前,在删除

6、File类的判断方法

    boolean exists()判断File构造方法中封装的路径是否存在,如果存在返回true

    boolean isAbsolute()判断File构造方法中封装的路径,是不是绝对路径,如果是绝对路径返回true

    boolean isDirectory()判断File构造方法中封装的是目录还是文件,如果是目录返回true

    boolean isFile()判断File构造方法中封装的是不是文件,如果是文件返回true

    boolean isHidden()判断File构造方法中封装的路径是不是隐藏属性,如果是发回true

7、File类的获取方法get开头

    String getName()获取的是File构造方法中封装的路径的最后那个部分的名字

    String getParent()获取File构造方法中封装的路径的父路径,返回String

    File getParentFile()获取File构造方法中封装的路径的父路径,返回File对象

    String getPath()将你File封装的路径,变成字符串

    File getAbsoluteFile()获取File构造方法封装的路径的绝对路径,返回File对象

    String getAbsolutePath()获取File构造方法封装的路径的绝对路径,返回String对象

8、File的获取方法,包含list

    static File[] listRoots()返回系统的根目录

    String[] list()获取File对象中封装的路径下的全部目录和文件夹,返回String数组

    File[] listFiles()获取File对象中封装的路径下的全部目录和文件夹,返回File数组,返回的是封装路径下的全部内容的全路径,可以继续使用File类的方法

    File[] listFileFileFilter filter)参数是文件过滤器,可以实现过滤想要的文件

9、File类的其他方法

    boolean renameTo(File file)对File构造方法中的封装的文件重命名,命名成功返回true,如果修改后的路径不同,出现剪切效果

    long lastModified()获取File构造方法中封装的文件的最后修改时间的毫秒值

10、File类的使用

 1 /*
 2  * 使用递归的编程方法,获取和删除一个目录下的全部内容
 3  */
 4 import java.io.*;
 5 public class GetAllFile {
 6     public static void main(String[] args)throws IOException {
 7         //getAllFile(new File("c:\\java"));
 8         deleteDir(new File("c:\\demo"));
 9         
10     }
11     
12     //删除一个目录
13     public static void deleteDir(File dir){
14         File[] files = dir.listFiles();
15         for(File f : files){
16             if(f.isDirectory())
17                  deleteDir(f);
18             else
19                 f.delete();
20         }
21         dir.delete();
22     }
23     
24     
25     //获取全部的内容
26     public static void getAllFile(File dir){
27         //通过方法listFiles()获取全部内容
28         File[] file = dir.listFiles();
29         for(File f : file){
30             //如果获取到的还是一个目录,进去遍历这个目录
31             //System.out.println(f);
32             if(f.isDirectory())//如果f是一个目录,进去获取
33                 getAllFile(f);
34             else
35                 System.out.println(f);
36         }
37     }
38 }

 

 

                                    递归

 

递归就是方法的自身调用,自己调用自己 public static void a(){ a(); }

使用递归:当你发现一个功能,运算的主体不变,但是,每次运算的参数都在变化,考虑使用递归实现功能

注意:

  递归必须要有条件限制

  递归不能太深,方法进栈次数不能过多,否则出现栈内存溢出

                                    

 

                                    流对象的使用规律

1、使用IO流对象的时候,进行文件的读写,应注意:

明确数据源

  如果操作的数据源是文本文件,可以选择字符输入流FileReader读取;如果需要提高流的读取效率,请你采用字符(char)数组缓冲;如果为了方便按行读取数据源,请你

  用BufferedReader来实现

  如果数据源不是文本文件,选择字节输入流FileInputStream读取;如果需要提高流的读取效率,请你采用字节(byte)数组缓冲;

  如果不能确定数据源到底是什么类型的文件,选择字节输入流FileInputStream读取

  互联网中的数据传输基本上是字节流

明确数据目的

  如果操作的数据目的是文本文件,可以选择字符输出流FileWriter写入;如果为了提高流的输出效率,请你采用字符数组(char)缓冲;如果为了方便按行输出数据目的,

  请你采用BufferedWriter来实现

  如果数据目的不是文本文件,选择字节输出流FileOutputStream写入;如果提高流的输出效率,请你采用字节(byte)数组缓冲

  如果不确定数据目的是什么类型文件,选择字节输出流FileOutputStream写入

如果数据源和数据目的都是字节流的,但是流中的内容又是纯文本数据,使用转换流来方便我们读取和写入

  读取使用InputStreamReader字节转成字符,按照行读取

  写入使用OutputStreamWriter字符转成字节,按照行写入

File对象,封装任意的目录和文件,可以将File对象传递给流对象进行写入或者读取,但是保证源和目的的文件类型。保证File对象封装的必须是文件,才能传递给IO流读取进行读取和写入

2、IO和集合综合应用的案例

 

 1 /*
 2  * 
 3  提供一个文本文件,文件中保存的是姓名和成绩
 4   读取文件,对姓名和成绩按照成绩高低排序
 5   将排序后的结果,保存到另一个文件中
 6   数据中姓名,成绩可能重复
 7   对于文件有要求,提供你的文件
 8  studentscore.txt 排序后另存的文件sortstudentscore.txt.  
 9  abc.txt    sortabc.txt
10  
11  IO,字符,File
12  集合List Collections
13  */
14 import java.util.*;
15 import java.io.*;
16 public class ScoreSort {
17     public static void main(String[] args) throws IOException{
18         //定义集合对象,存储文本中的姓名和成绩
19         List<Student> list = new ArrayList<Student>(); 
20         //定义File对象,文件进行封装
21         File file = new File("c:\\student.txt");
22         //定义字符输入流,读取源文件
23         BufferedReader bfr = new BufferedReader(new FileReader(file));
24         String line = null;
25         while((line = bfr.readLine())!=null){
26             //字符串处理,切割,姓名和成绩
27             line = line.trim();
28             String[] str = line.split(" +");
29             //姓名str[0],成绩str[1]转成int,存储到集合
30             list.add(new Student(str[0],Integer.parseInt(str[1])));
31         }
32         //集合排序了,Collections工具类中的方法 sort,排序的是自定义对象
33         Collections.sort(list,new MyComparatorStudent());
34         //将排序后的内存,存储到新的文本文件中,要求文件名前面加sort
35         //获取源文件的文件名
36         String filename = file.getName();
37         filename = "sort"+filename;
38         
39         //获取源文件的父路径
40         String parent = file.getParent();
41         
42         //父路径和文件名组成File对象,传递给字符输出流写文件
43         File newFile = new File(parent,filename);
44         BufferedWriter bfw = new BufferedWriter(new FileWriter(newFile));
45         for(Student s : list){
46             bfw.write(s.getName()+" "+s.getScore());
47             bfw.newLine();
48             bfw.flush();
49         }
50         bfr.close();
51         bfw.close();
52     }
53 }

 

 

 

 

 

 1 import java.io.*;
 2 /*
 3  * 复制文件夹
 4  * 分析:
 5  *         1:目录下包含有目录和文件。
 6  *         2:用递归实现这个操作,判断是目录就创建。是文件就创建并拷贝。
 7  * 
 8  *         把d盘目录下的source目录内容拷贝到e盘目录下。
 9  */
10 public class Copy {
11     public static void main(String[] args)   {
12         File source = new File("c:\\source");
13         File target = new File("d:\\");
14         copyDir(source, target);
15     }
16 
17     // 拷贝目录
18     private static void copyDir(File source, File target) {
19         // 判断source
20         if (source.isDirectory()) {
21             // 是目录
22             // 在target下创建同名目录
23             File dir = new File(target, source.getName());
24             dir.mkdirs();
25             // 遍历source下所有的子文件,将每个子文件作为source,将新创建的目录作为target进行递归。
26             File[] files = source.listFiles();
27             for (File file : files) {
28                 copyDir(file, dir);
29             }
30         } else {
31             // 是文件
32             // 在target目录下创建同名文件,然后用流实现文件拷贝。
33             File file = new File(target, source.getName());
34         //    file.createNewFile();
35             copyFile(source, file);
36         }
37     }
38 
39     // 拷贝文件
40     private static void copyFile(File source, File file)   {
41         // 创建流对象
42         InputStream is = null;
43         OutputStream os = null;
44         try {
45             is = new FileInputStream(source);
46             os = new FileOutputStream(file);
47 
48             // 基本读写操作
49             byte[] bys = new byte[1024];
50             int len = 0;
51             while ((len = is.read(bys)) != -1) {
52                 os.write(bys, 0, len);
53             }
54         } catch(IOException e){
55             throw new RuntimeException("复制失败");
56         }finally {
57             try{
58             if (os != null) {
59                 os.close();
60             }
61             }catch(IOException e){
62                 
63             }
64             
65             try{
66             if (is != null) {
67                 is.close();
68             }
69             }catch(IOException e){
70                 
71             }
72         }
73     }
74 
75 }

 

 

                                        打印流

 Java.io.PrintStream

 java.io.PrintWriter

1、 打印流的特点:打印流只操作数据目的,不操作数据源。打印流永远不会抛出IO异常。

   System.out 获取到打印流对象PrintStream

2、 PrintStream构造方法,传递的是打印流的输出目的

    可接受 File对象、字节输出流对象、字符串的文件名

   PrintWrtier类实现了PrintStream类的所有print方法,区别在于构造方法不同

        可传递File对象、字节输出流、字符串文件名、字符输出流

3、 打印流中,实现换行输出,使用println()方法。

  打印流自动刷新的前提:

    打印流中,构造方法可以写boolean值,如果是true,开启自动刷新。

  打印流中传递的对象,必须是流对象才行 new PrintWriter(输出流对象, true)

  必须调用println,printf,format三个方法,才能实现自动刷新 

4、打印流的好处:

  简单,方便,自动刷新,不出异常

  用处:

  用在Java的服务器端程序,可以把数据,使用打印流写给客户端浏览器

5、打印流的案例

  使用打印流对象PrintWrtier,替代转换流,字符转成字节,OutputStreamWriter,实现数据的打印功能。OutputStreamWriter(System.out)

  

 1 /*
 2  * 打印流替换转换流,OutputStreamWriter
 3  */
 4 import java.io.*;
 5 public class PrintWriterDemo1 {
 6     public static void main(String[] args)throws IOException {
 7         BufferedReader bfr = new
 8                 BufferedReader(new InputStreamReader(System.in));
 9         /*BufferedWriter bfw = new
10                 BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\11.txt")));*/
11         //打印流,替换转换流
12         File file = new File("c:\\ffffff.txt");
13         PrintWriter pw = new PrintWriter(new FileWriter(file),true);
14         
15         String line = null;
16         while((line = bfr.readLine())!=null){
17             if("over".equals(line))break;
18              pw.println(line.toUpperCase());
19         }
20         pw.close();
21         bfr.close();
22     }
23 }

 

 

 

 注: PrintWriter类属于Writer的子类,字符流,只能操作文本数据。如果操作的不是文本数据,纯字节流

                                          对象的序列化

1、序列化,将对象的数据保存到硬盘 -- ObjectOutputStream,字节流

   ObjectOutputStream构造方法中,传递一个字节输出流对象,对象就会写进字节输出流封装的文件

     写对象的方法 void writeObject(Object obj)

 

  反序列化,将硬盘中的对象数据读取出来 -- ObjectInputStream,字节流

  ObjectInputStream构造方法中,传递一个字节输入流对象,字节输入流对象封装一个文件,读取封装的文件中的对象

  读取对象的方法 Object readObject() 抛出IO异常(可能找不到class文件)

   

2、 类必须实现java.io.Serializable接口,启用序列化功能

 

   Serializable接口:

 

       接口没有任何抽象方法,实现接口后,不需要重写方法。凡是以后我们在看到没有抽象方法接口,这样的接口,标记型接口。

      作用是:告诉JVM可以序列化

 

 注意:

    把成员变量加上了static后,序列化没有问题,但是反序列化的时候,成员变量的值丢失,原因序列化的时候,文件没有保存静态变量的值。

    序列化是对象的序列化,静态成员变量,属于类,不属于对象,因此静态不能序列化

 

3、java.io.InvalidClassException,序列号冲突。

 

      产生原因:Person类写好后,进行了对象的序列化,Person.class,person.txt(序列化文件)产生了,存储了同一个序列号。可是我么将Person类的原始代码进行了修改,会重新的编          译,生成了一个新的Person.class文件。而person.txt中记录的序列号已经和person.class中的不一致了。当又进行了反序列化,就导致Person.class中的序列号person.txt          中的序列号出现冲突问题。

    解决办法:自定义序列号

 

           static final long serialVersionUID = 自定义的long型数据;

 

                                        Properties和IO的结合

1、 Properties是双列的集合 , Hashtable的子类,线程安全的。完全可以使用操作Map的方法和步骤,操作Properties

 

 

  Properties自己的特性:  getProperty()  setProperty()方法的参数定死为String

  Properties如何与IO流结合使用:用于书写配置文件

 

      将读取到的文件中的键值对,存储到 Properties集合中

        Properties的方法load(字节输入流)   load(字符输入流) 

      将集合中的键值对修改后,存储到文本文件

         store(字节输出流,"")  store(字符输出流,"")    ”“注释修改原因,一般不写

 

      将属性列表输出到指定的地方:

        list(打印流)        

 

 

                                RandomAccessFile随机读写流

1、随机读写流的特点:

    直接继承Object类

    这个类封装了一个大型的字节数组

    可以读,可以写

    随机访问:可以从文件的任意位置开始读写。移动文件指针的方法:seek(long l)

    可以读取基本数据类型

 2、RandomAccessFile的构造方法

     两个参数,一个是File类型包装一个文件,Stirng类型mode,一般为"rw"

     两个参数,一个是String类型文件名,String类型mode,一般为"rw"

 

3、随机读写流读写一个文件

 

 1 /*
 2  * 实现随机读写
 3  */
 4 import java.io.*;
 5 public class RandomAccessFileDemo1 {
 6     public static void main(String[] args) throws IOException{
 7 //        write();
 8         readAll();
 9 
10     }
11     //读取的方法,读取文件的全部内容
12     private static void readAll()throws IOException{
13         RandomAccessFile raf = new RandomAccessFile("c:\\ran.txt", "rw");
14         byte[] bytes = new byte[4];
15         int age = 0;
16         while(true){
17             try{
18                 raf.read(bytes);
19                 age = raf.readInt();
20                 System.out.println(new String(bytes)+age);
21             }catch(Exception e){//读取基本数据类型时,-1也有可能是对的,所以要用异常跳出循环
22                 break;
23             }
24         }
25     }
26     
27     //读取文件,随机读取
28     private static void read()throws IOException{
29         RandomAccessFile raf = new RandomAccessFile("c:\\ran.txt", "rw");
30         //偏移指针
31 //        raf.seek(8);
32         byte[] bytes = new byte[4];
33         raf.read(bytes);
34         int age = raf.readInt();
35         System.out.println(new String(bytes)+age);
36     }
37     
38     
39     //写张三65
40     private static void write()throws IOException{
41         RandomAccessFile raf = new RandomAccessFile("c:\\ran.txt", "rw");
42         raf.write("张三".getBytes());
43         raf.writeInt(65);
44         
45         raf.seek(16);
46         raf.write("李四".getBytes());
47         raf.writeInt(66);
48         //将文件指针,偏移到8字节
49         raf.seek(8);
50         raf.write("王武".getBytes());
51         raf.writeInt(67);
52         raf.close();
53     }
54 }

 

 

 

注:上诉的异常为EOFException 文档结尾异常

  实现随机读写,需要文件存的数据有规律

 

 

 

 

           

posted @ 2014-08-20 23:09  Love_Ezreal  阅读(168)  评论(0编辑  收藏  举报