只是小人物

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、File类的有什么作用
   java.io.File 用于表示文件(目录),也就是说程序员可以通过File类在程序中操作硬盘上的文件和目录.
   File类只用于表示文件(目录)的信息(名称  大小等),不能对文件内容进行访问(访问用RandomAccessFile)
二、 java.io.File 基本 API
 File 代表文件系统中对文件/目录的管理操作(增删改查, CRUD)
 常用API方法:
  File(String)   指定文件名的构造器
  long length()    文件的长度
  long lastModified()  最后一次修改的时间(是个long)
  String getName()  返回由此抽象路径名表示的文件或目录的名称。
  String getPath()   将此抽象路径名转换为一个路径名字符串
  boolean exists()   检查是否存在
  boolean dir.isFile()  检查是否是文件
  boolean dir.isDirectory() 检查是否是目录/文件夹
  boolean mkdir()   创建一个目录
  boolean mkdirs()  创建一系列目录(demo/sub/sub同时创建3个文件夹)
  boolean delete()   删除此抽象路径名表示的文件或目录
       (如果此路径名表示一个目录,则该目录必须为空才能删除。 )
  boolean createNewFile() throw IOException 当且仅当不存在具有此抽象路径名指定名
           称的文件时,不可分地创建一个新的空文件 
  File[] listFile()   返回一个抽象路径名数组,这些路径名表示此
       抽象路径名表示的目录中的文件

例子:

 1 import java.io.File;
 2 import java.io.IOException;
 3 /**
 4  *  文件系统的管理 :pwd,ls
 5  *
 6  */
 7 public class FSDemo {
 8 
 9  public static void main(String[] args) throws IOException {
10   /*注意:Java程序的当前目录:是JAVA程序的启动文件夹,在
11    * ECLIPSE开发的项目中,启动文件夹是项目文件夹,就是当前目录*/
12   File dir = new File(".");//当前目录
13   
14   //getCanonicalPath():返回的规范的路径名,不包括: . .. 
15   String path = dir.getCanonicalPath();
16   System.out.println(path);
17   
18   //getAbsolutePath(): 返回绝对路径,可能包含 :. ..
19   path = dir.getAbsolutePath();
20   System.out.println(path);
21   //以上代码相当于:Linux的pwd命令
22   
23   //File demo = new File("demo");//相对路径
24   File demo = new File(dir,"demo");//dir是父目录,这里的dir就是.(当前目录)
25   
26   //new File()只是在内存中创建对象,不代表在硬盘上创建文件夹
27   //或文件,可以使用方法exists()检查文件/文件甲是否存在
28   
29   System.out.println(demo.exists());//false
30   //检查当前目录下有没有demo文件对象
31   if(!demo.exists()){
32    demo.mkdir();//创建文件夹
33    //demo.mkdirs();创建系列文件夹,如:demo/sub/sub
34   }
35   File file = new File(demo,"demo.txt");
36   if(!file.exists()){
37    file.createNewFile();//创建文件,
38   }
39   System.out.println(file.isDirectory());//false
40   System.out.println(file.isFile());//true
41   System.out.println(demo.isDirectory());//true
42   System.out.println(demo.isFile());//false
43   
44   System.out.println(file.canRead());//true 该文件是否可读
45   System.out.println(file.isHidden());//false  该文件或目录是否为隐藏
46   System.out.println(file.lastModified());//1334837570000(返回long的毫秒数)
47   System.out.println(file.length());//0
48   
49   file.delete();//删除文件
50   demo.delete();//只能删除空文件夹
51  }
52 }

 

例子2

 1 import java.io.File;
 2 import java.util.Arrays;
 3 import java.util.Comparator;
 4 
 5 public class ListFileDemo {
 6  public static void main(String[] args) {
 7   //以下代码相当于linux的ls命令
 8   File dir = new File("/etc");//在linux操作系统下
 9   File[] files = dir.listFiles();
10   for(File file: files){
11    System.out.println(file);
12   }
13  }
14 
15 }

 

三 回调模式和FileFilter
 FileFilter 类是对操作文件的过滤,相当于Linux命令:ls|grep p
  API 方法 :File[] listFile(FileFilter)

 1 import java.io.File;
 2 import java.io.FileFilter;
 3 
 4 public class ListFilesDemo2 {
 5  public static void main(String[] args) {
 6   //ls /etc |grep p
 7   File dir = new File("/etc");
 8   /*dir.listFiles(filter)重载的列目录方法,参数是过滤条件
 9   根据过滤条件过滤列目录的结果
10   FileFilter 接口,声明了过滤方法accapt(file) 如果这个方法返回
11   true,表示这个文件被接受,保留作为方法的结果
12   */
13 
14   File[] files = dir.listFiles(new FileFilter(){
15    public boolean accept(File file){ //此方法的调用属于回调模式(不用自己去调用)
16     return file.isFile() && 
17     file.getName().matches(".+p.+");//此处代表文件名中有p,可用正则表达式
18    }
19   });
20   for(File file:files){
21    if(file.isDirectory()){//根据是文件夹还是文件作出有差别的打印
22     System.out.println("["+file.getName()+"]");
23    }else{
24     System.out.println(file.getName());
25    }
26   }
27  }
28 }

 

四 RandomAccessFile
RandomAccessFile类有什么用?

   RandomAccessFile类是Java提供的功能丰富的文件内容访问类,它提供了多种方法访问文件
内容,既可以读取文件内容,也可以向文件输出数据,RandomAccessFile支持"随即访问"方式,可以访问文件的任意位置

1)Java 文件模型,文件是byte by byte 是数据集合
data : 41 42 00 00 00 ff d6 d0 ……
index: 0 1 2 3 4 5 6 7 ……
porinter: ^
注意:data中为16进制数
16进制:41 对应 0100 0001 是一个字节

1024*1024*1024*1024
  k     M        G      T
5M Byte = 5 * 1024 * 1024个Byte组成的序列

2) 打开文件,有两种模式"rw"(读写),"r"(读)
RandomAccessFile raf = new RandomAccessFile(file,"rw");
打开文件时候默认文件指针在开头 pointer = 0

3)写入方法:raf.write(int)将整整的" 低八位"写入到文件中,
   指针自动移动到下一个位置,准备再次写入

* 文件名的扩展名要明确指定,没有默认扩展名现象!

4)读取文件
   int b = raf.read() 从文件中读取一个byte(8位)填充到int 的低8位,高24位为0,返回值
范围整数:0-255,如果返回-1表示读取到了文件末尾!每次读取后自动移动文件指针,准备下次读取

5) 文件读写完成以后一定要关闭文件
   Sun官方说明,如果不关闭,可能遇到一些意想不到的错误,根据具体操作平台不同会有不同
在使用过程中,切记文件读写完后要关闭文件.


例子

 1 import java.io.FileNotFoundException;
 2 import java.io.IOException;
 3 import java.io.RandomAccessFile;
 4 /**
 5  * 随机读写文件 
 6  * data: 41 42 ff ff ff fe
 7  * index:  0  1  2  3  4  5  6
 8  * pointer:        ^
 9  */
10 public class RAFDemo {
11  public static void main(String[] args) throws IOException {
12   String file = "raf.dat";
13   RandomAccessFile raf = new RandomAccessFile(file,"rw");
14   System.out.println(raf.length());//0
15   System.out.println(raf.getFilePointer());//0
16   raf.write(0xffffff41);//底八位是41,前面的f没用,向文件写入41
17   System.out.println(raf.getFilePointer());//1
18   raf.write(66);//向文件写入42(十六进制)
19   System.out.println(raf.getFilePointer());//2
20   //如何将 -2 写入到文件!
21   int i = -2;//Oxfffffffe
22   //raf.write(i);//写入的是fe(高24位舍弃),不是-2
23   //>>>:无符号移位运算(向右移动数位,低位溢出,高位补0)
24   //>>  有符号移位运算,向右移动数位,低位溢出,高位正数补0,负数补1,保证符号不变
25        //i = 11111111 11111111 11111111 11111110
26   raf.write(i>>>24);//00000000 00000000 00000000 11111111 
27   raf.write(i>>>16);//00000000 00000000 11111111 11111111
28   raf.write(i>>>8); //00000000 11111111 11111111 11111110
29   raf.write(i);   //11111111 11111111 11111111 11111110
30   
31   System.out.println(raf.getFilePointer());//6
32   String str = "中国";
33   byte[] buf = str.getBytes("GBK");//将"中国"转为GBK编码
34   raf.write(buf);
35   
36   //读取文件内容
37   System.out.println("读取文件内容");
38   raf.seek(0);//使pointer回到0
39   int b = raf.read();//读41,同时poiner+1
40   System.out.println(Integer.toHexString(b));//用16进制打印出来41
41   b = raf.read();//读42,同时poiner+1
42   System.out.println(Integer.toHexString(b));//用16进制打印出来42
43   
44   System.out.println("重新读取文件内容");
45   raf.seek(0);//使pointer回到0
46   while((b= raf.read()) != -1){
47    ;//读一个,同时poiner+1
48    System.out.println(Integer.toHexString(b));//用16进制打印出来
49   } 
50   raf.close();//关闭文件
51  }
52 }

 

五 序列化与基本类型序列化

1) 什么叫序列化?
  将类型int转换为4byte,或者将其他数据类型(如long -> 8byte)的过程,即将数据转换
为 n 个 byte 序列叫做序列化(数据 -> n byte)

2)什么是反序列化?
 将n byte 转换为一个数据的过程(n byte -> 数据)
如:[7f, ff, ff, ff] -> 0x7fffffff

3)RandomAccessFile 提供基本数据类型的读写方法,可以将基本类型数据序列化到文件或者将文件内容反序列化为数据
例子:

 1 import java.io.IOException;
 2 import java.io.RandomAccessFile;
 3 /**
 4  * 文件的最基本的操作 就是每次读/写 一个byte数据
 5  * 
 6  * 序列华 : 数据(int long double)需要拆分为 byte序列写入到文件
 7  * 反序列化: 将byte重新拼接为数据
 8  * 
 9  * image 在内存中是对象,写到文件中,需要进行序列化,有标准:jpg
10  */
11 public class DataIODemo {
12 
13  public static void main(String[] args) throws IOException{
14   // TODO Auto-generated method stub
15 
16   //如何写出基本类型,读取基本类型
17   String file = "data.dat";
18   RandomAccessFile raf = new RandomAccessFile(file,"rw");
19   
20   raf.writeInt(-2);//将int -2 拆分为4个byrte写到文件中
21   raf.writeLong(-2L);
22   raf.writeDouble(-2.0);
23   raf.writeBoolean(true);
24   
25   raf.seek(0);
26   int i = raf.readInt();//pointer 4
27   long l = raf.readLong();//pointer 8
28   double d = raf.readDouble();//pointer 12
29   boolean b = raf.readBoolean();//pointer 16
30   raf.seek(12);
31   double x = raf.readDouble();
32   System.out.println(i+","+l+","+d+","+b+","+x);
33   
34   raf.close();
35   IOUtils.print(file);
36 
37  }
38 
39 }

 


序列化和反序列化的原理如下

 1 import java.io.IOException;
 2 import java.io.RandomAccessFile;
 3 
 4 public class RAFDataIODemo {
 5  public static void main(String[] args)throws IOException{
 6   String file = "raf.dat";
 7   IOUtils.print(file);//41 42 ff ff ff fe d6 d0 b9 fa 
 8   RandomAccessFile raf = new RandomAccessFile(file,"r");
 9   //如何读取int数据,使用readInt()
10   //原理
11   raf.seek(2);
12   int d1 = raf.read();// 00 00 00 ff
13   int d2 = raf.read();// 00 00 00 ff
14   int d3 = raf.read();// 00 00 00 ff
15   int d4 = raf.read();// 00 00 00 fe
16   //(d1<<24) : ff 00 00 00
17   //(d2<<16) : 00 ff 00 00
18   //(d3<< 8) : 00 00 ff 00
19   //(d4  ) : 00 00 00 fe
20   // i      : ff ff ff fe
21   int i = (d1<<24) + (d2<<16) + (d3<<8) + d4;
22   System.out.println(i);
23   //使用readInt()
24   raf.seek(2);//pointer重回2
25   i = raf.readInt();
26   System.out.println(i);
27   
28   
29   //读取中文
30   raf.seek(6);
31   byte[] buf = new byte[4];//4个byte的缓冲区
32   //raf.read(byte[])从raf尽可能多的读取byte数据填充到buf中
33   //返回读取的个数,返回值介于0~缓冲区大小之间,如果返回-1,表
34   //示读取到了文件尾部!
35   int n = raf.read(buf);
36   //String(byte[] byte,int start,int size,编码方式)
37   String str = new String(buf, 0, n,"GBK");
38   System.out.println(str);//中国 
39   raf.close();
40  }
41 }

 


 

posted on 2012-04-19 22:32  只是小人物  阅读(1687)  评论(0编辑  收藏  举报