Java核心类库——文件和文件夹的管理File类
转载自 http://www.cnblogs.com/hqr9313/archive/2012/04/19/2458529.html
一、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 }