黑马程序员16——IO流3

来源:互联网 发布:linux登陆时间 编辑:程序博客网 时间:2024/06/14 14:14

------- android培训、java培训、期待与您交流! ----------


1. File类的作用

  IO流对象,读写文件
  File类,不属于流对象,不可以读写文件
  将系统的路径E:\2014\06-24\day23,还有文件夹,封装成对象来处理
  File提供了大量的方法,帮助我们处理系统中的路径和文件夹
  File类中的方法,IO流配合起来


  专门处理路径和文件夹一个类,File类具有平台无关性,看JVM是哪一个操作系统版本的


2. File类中的2个静态的常量
  File.pathSeparator 结果 ; Windows系统中,表示一个路径的结束
                            Linux系统中,表示一个路径结束 :
  
  File.separator; 结果 \ Windows下的路径的分隔符号
                         Linux系统中,路径分隔符 /


3. File类的构造方法
    带有一个String的构造方法
     new File(String pathname)传递一个路径名字
     将传递的路径名字,封装成File对象,可以使用File类的方法
     无论写的路径,有和没有,没有关系,构造方法只是将写的路径变成File对象


    带有两个String的构造方法
    new File(String 父路径,String 子路径)
    什么是父路径,子路径
    必须先有一个路径
        c : \\programFiles\\java\\jdk1_7_09
    对于Java路径而言,父路径(上一级文件夹)programFiles
    对于Java路径而言,子路径(下一级文件夹)jdk1_7_09


   带有两个参数的File父路径,String类型子路径
   new File(File parent,String 子路径)


4. File类中的常见方法--创建功能
  File类的创建文件功能


  boolean createNewFile() 创建一个新的文件
  创建的文件的路径和文件名在哪里,创建File对象构造方法中,封装的哪个路径
  如果文件已经存在,不会再次创建.
  只能创建文件




  File创建文件夹
  boolean mkdir()创建一个新的文件夹
  只能创建一级文件夹


  boolean mkdirs()创建多级文件夹子
  推荐使用带s的方法,不带s的局限性很大


5. File类的常见方法--删除功能
  boolean delete()删除,File对象构造方法中封装的哪个路径
  删除成功,返回true
  不走回收站,直接永久性删除
  不能直接删除非空目录




  void deleteOnExit()删除File对象构造方法中封装的路径
  这个方法,不会立刻删除,延迟,程序全部结束了,在JVM退出之前,进行删除


  凡是做删除,必须给用户提示


 6. File类的常见方法--判断方法
  boolean exists() 判断File构造方法中封装的路径是否存在
  存在返回true


  boolean isAbsolute()判断File构造方法中封装的路径是不是绝对路径
  据对路径,都是以盘符开始的


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


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


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


 7. File类的常见方法--获取方法
   static File[]  listRoots()返回系统根,跨平台性


   String getName()获取名字,获取File对象封装的路径的名字


   String getParent()获取父路径,获取File对象封装的路径的父路径


   File getParentFile() 获取父路径,返回值是File类型


   String getPath()获取路径的字符串,将File对象封装路径,变成String


   File getAbsolute()返回File对象封装的路径的绝对路径
 
   String getAbsolutePath() 返回File对象封装的路径的绝对路径,返回值是String
 
 8. File类的其他方法
   boolean renameTo(File f)修改文件名,或者文件夹名
   看File构造方法中封装的路径是什么
   修改前,和修改后,不在同一个目录,这个方法,带有剪切效果


   long lastModified() 获取文件的最后修改时间的毫秒值


   当这个文件很重要是:我修改完毕后,记录下修改时间的毫秒值
   n长时间后,再次获取这个毫秒值,两个值不一样,文件被别人动过手脚


 9. File创建方法--list开头
   String[]  list()获取File构造方法中封装的路径下的全部文件夹和文件
   只有文件和文件夹名字
   File[]  listFiles()获取File构造方法中封装的路径下的全部文件夹和文件
   返回全路径
   都可以获取到所有的内容,包含隐藏属性的




   文件过滤器,过滤调listFiles方法不想要的文件
   如何过滤呢?
   File[] listFiles(FileFilter filter) 
   接口FileFilter filter 文件过滤器
 
   如果使用listFiles方法,参数,传递的是FileFilter的接口的实现类对象


   自己写一个文件过滤器,实现FileFiter接口


   class MyFileFilter implements FileFilter{
      public boolean accept(File pathname) {
return true;
}
   }
   listFiles(new MyFileFilter())
   accept(File pathname)由谁调用
   参数传递过来,pathname的结果是什么
   pathname结果就是listFiles遍历到的所有文件和文件夹的全路径名


   如果accept方法,返回真,需要这个文件,返回假,不需要这个文件
   让文件名是.java的返回真
    return pathname.getName().endsWith(".java");


 10. 递归
   递归,是一种编程手法,一种技巧
   不是java语言特有,C php 都具有


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


   从前有个山,山里有个庙,庙里有个老和尚讲故事,讲的是,从前有个山,山里有个庙,庙里有个老和尚讲故事,将的是从前有个山




   计算一个十进制的二进制
   6 ==> 110
   编写程序,计算一个十进制的二进制,不能用JDK中已有的方法


    递归到底什么时候用:
      条件:当我们定义一个方法的时候,发现方法运算的主体不变,但是每次计算的参数发生变化
      考虑使用递归
    
    注意:
      递归必须有条件,控制它,不能无限的进栈
      递归的次数,不要过大


11. 递归实现文件目录的全遍历
   定义方法,实现目录遍历
   发现方法主体运算,都是在遍历目录,每次遍历的目录不同
   c:\demo
   c:\demo\a
   c:\demo\b
package cn.itcast.iostream;/* * 使用递归方法,遍历目录下的全部,包括子目录 */import java.io.File;public class FileDemo8 {public static void main(String[] args) {deleteDir(new File("c:\\demo"));}/* * 删除目录 * 删除的目录不是空的,遍历目录,从里面向外删除 * 从最内层文件夹,删除里面的文件,删除这个文件夹 */private static void deleteDir(File dir){File[] file = dir.listFiles();for(File f : file){if(f.isDirectory())deleteDir(f);elsef.delete();}dir.delete();}/* * 传递一个目的,遍历全部 */private static void getAllFile(File dir){//获取dir下面的所有内容File[] file = dir.listFiles();for(File f : file){//System.out.println(f);//判断f遍历到的是一个目录,文件夹if(f.isDirectory()){//继续遍历这个目录getAllFile(f);}else{System.out.println(f);}}}}



   杀毒软件,扫描硬盘的时候,递归方式

=======================================

1. 复制单级目录



  文件夹是不能复制,方法创建的
  main(){
  copyDir(new File("c:\\demo"),new File("d:\\"))
  }


  private static void copyDir(File srouce,File target){
  
  }


  第一步:获取源的文件夹名字 getName() 
         将名字,目的d:\\组成新的File对象
File对象mkdirs目录创建出来


  第二步:遍历源,获取目录下的文件
         获取到所有的文件的全路径
c:\\demo\\abc.rar
获取源的文件名 getName()


将文件名和目的路径组成新的File对象
d:\\demo\\abc.rar


  第三步:将源和目的传递给字节流,读写文件,单独写一个方法


2. 打印流
  PrintStream
     System.out返回对象就是打印流对象
  PrintWriter


  打印流的特点:
    A。为其他输出流添加了功能,方便打印各种形式的数据
    B. 打印流对象,永远不会抛出IO异常,原因是这个流对象,只操作数据目的,不操作数据源
  
  使用打印流的时候,需要在打印流构造方法中传递输出流就可以了


  PrintStream构造方法,接收哪些参数
    File对象
    字节输出流
    String文件名


  new PrintStream(输出流)
  print println




  PrintWriter -- 实现了PrintStream中的所有的print方法
  PrintWriter构造方法,接收哪些参数
    File对象
    字节输出流
    String文件名
    字符输出流


   Sun工程师,方便打印各种数据,避免每次刷新
   开发出了新的功能,打印流的自动刷新功能
   打印流的构造方法中,如果传递的是输出流对象,可以是字节,可以是字符,可以加上一个参数
   true,开启自动刷新
   如果启用了自动刷新,必须调用println prinf format三个方法,才有效


   日后的开发中,打印流的应用在哪里
   在服务器端,使用打印流将数据打印回客户端浏览器




   打印流案例:替代转换流,将数据打印到任意目的地


   PrintWriter pw = new PrintWriter(new FileOutputStream(new File("c:\\abc.txt")),true);
   打印流传递的对象
     第一个结果  new File
     第二个结果  FileOutputStream(File对象)
     第三个结果  PrintWrtier(字节输出流)


 3. 对象的序列化和反序列化
   将对象中的数据写在文件中,对象的序列化
   将文件中写的对象的读取,读取出来,对象的反序列化
   
   Java.io包中,提供了读写对象的类
   ObjectInputStream 反序列化,读取对象
   ObjectOutputStream 序列化,写出对象


   ObjectOutputStream,写对象
   构造方法,传递一个字节输出流,对象写在这个流中
   void writeObject(Object obj) 写一个对象
 


   ObjectInputStream,读取对象
   构造方法,传递一个字节输入流,读取文件
   Object readObject()  读取一个对象
 


   Exception in thread "main" java.io.NotSerializableException: cn.itcast.iostream.Person
   类Person没有开启序列化功能,Person类实现java.io.Serializable接口,开启序列化功能


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


   java.io.Serializable接口,类实现了它,开启了序列化功能
   没有抽象方法,凡是以后见到没有抽象方法的接口,标记型接口
   相当于在你的实现类了,盖了一个章,开启序列化


   买过猪肉,蓝色的章,年月日,出厂合格猪




   Exception in thread "main" java.io.InvalidClassException: cn.itcast.iostream.Person;
   local class incompatible: stream classdesc serialVersionUID = 644662000238922631, local class serialVersionUID = 4733875578997969149


   进行Person的序列化的时候,private int age;
   写出了一个对象,obj.txt  Person.class,记录同一个序列号  123


   Person类的 public int age;
   从新编译后,生产了新的Person.class文件,记录另一个序列号  456
   obj.txt  序列号还是123


   序列号怎么来的
     public static final  private 内存不认识,010101010
     JVM内部,对这些个修饰符,有一个数字表示,public 101010101
     private 11110000




   处理一下序列号不匹配的问题
     如果修改了源代码以后,不影响序列化功能,可以保证,修改源码以前,和修改源码以后的序列号不变
     修改源码之前,序列化一次,修改后,不在序列化,保证序列号的一致性


     javac 编译的时候,JVM根据源码从新计算序列化,编译的时候,不让JVM从新计算序列号 
     Person类,手动定义一个序列号,只要我们自己定义了,JVM不在从新计算了


 4. Properties类
   集合,存储键值对的集合,Hashtable子类,线程安全的
   可以直接使用Map中的方法,操作这个集合


   这个类的自己的特有方法
     String getProperty(String key) 通过键获取值,Map中的get一样,数据类型定死为String
     Object setProperty(String key, String value) 将键值对存储到集合,Map中的put一样,数据类型定死String
 以后使用Properties类,存储和获取键值对 自己的方法get set ... Property


   使用集合IO结合起来
   IO读写文件的,集合存储键值对
   IO读取一个文件中的键值对,存储到集合
   集合中有一个方法load,关联IO流对象
   load(字节,字符,输入流)


   使用load直接从流中读取了键值对
   集合中如果修改了这个键值对,如何存储回文件呢


   store()方法,可以将集合中的键值对,写回文件
   (OutputStream out, String comments) 字节输出流,注释,写上为什么要改这个文件


   文档中,键值对,前面写了一个#,说明这个是注释
   IO流不要会读取这个#号的


   题目:
     集合中的load传递字节输出流,字符输出流
     自己定义方法,实现load功能
     要求重载形式,一个传递字节输出流,一个传递字符输出流
     读取一个文件,键值对存储到集合


 5. RandomAccessFile 随机读写
   不属于字节流,和字符流体系


   此类的实例支持对随机访问文件的读取和写入。


   这个类对象,支持随机访问文件,可以从文件的任意位置读和写
   支持读取和写入
   类中,有一个文件指针,随机的移动指针的位置
   seek(10)传递long型的数据,移动指针位置


   使用随机读写类,构造方法
   RandomAccessFile(String name, String mode) 
   传递两个参数,第一个字符串文件名,第二个是 String的模式  "rw"


   这个类的读写可以操作基本数据类型
   write(65) A
   0000-0000 0000-0000 0000-0000 0100-0001


   RandomAccessFile 读写基本类型方法
   writeInt()int 32个二进制,4个字节
   readInt() int 32个二进制,4个字节
   读取的时候read()文件末尾返回-1


   readInt()读取基本数据类型int
   读取到文件默认,不能返回-1,抛出异常 EOFException /End Of File

0 0
原创粉丝点击