您的位置:首页 > 编程语言 > Java开发

JavaSE第八十七讲:File类详解及使用陷阱深度剖析

2013-01-19 14:48 741 查看
1. 结合上一讲内容,我们继续对Java中的IO系统File类进行剖析

1) 上一讲中我们讲到了File类的四种构造方法,其中我们只用到第二种构造方法public File(String pathname),查看JDK 文档中的File类的构造方法,下面我们练习使用第一种构造方法:public File(File parent, String child),第一个参数表示目录,第二个参数表示文件,这个构造方法表示在parent目录下创建一个child文件.其实是将上一个构造方法的参数,表示字符串类的一个目录。拆分成两个部分一个表示目录,另外一个表示文件。

package com.ahuier.io;

import java.io.File;

public class FileTest2 {
public static void main(String[] args) throws Exception{

File file = new File("c:/abc/xyz");
/*
* 表示在指定目录"c:/abc/xyz"下,创建hello.txt文件,注意目录必须存在,如果目录不完整则无法创建文件,会异常
*/
File file2 = new File(file, "hello.txt");
file2.createNewFile();
}
}
编译执行结果会在指定目录下c:/abc/xyz生成文件hello.txt
【说明】:以上main代码也可以写成:

public static void main(String[] args) throws Exception{

File file = new File("c:/abc");
/*
* 表示在指定目录"c:/abc/xyz"下,创建hello.txt文件,注意目录必须存在,如果目录不完整则无法创建文件,会异常
*/
File file2 = new File(file, "xyz/hello.txt");
file2.createNewFile();
}
编译执行同样成功创建,所只要参数1,和参数2拼接起来能够形成一个完整的目录结构则就会编译成功的。
【注意】:上面两种方式都必须在指定目录下完整情况下才能创建好这个文件,否则就会出现异常。

2) 继续查看其他的构造方法:public File(String parent, String child) 这个方法与上面一个方法本质上一样的,它第一参数接受的是String类型。

package com.ahuier.io;

import java.io.File;

public class FileTest2 {
public static void main(String[] args) throws Exception{

/*
* 表示在指定目录"c:/abc/xyz"下,创建hello.txt文件,注意目录必须存在,如果目录不完整则无法创建文件,会异常
*/
File file2 = new File("c:/abc", "xyz/hello.txt");
file2.createNewFile();
}
}
【说明】同样也是第一参数与第二个参数拼接起来能构造成一个完整的路径即可创建成功。

2. Java中文件和目录都是用File类型来表示,File类中提供了两个方法来区分是否为目录或者文件。

public boolean isDirectory()  判断是否为目录

public boolean isFile()       判断是否为文件

3. File类中的目录管理和文件管理

1) 目录管理,目录操作的主要方法为:

public boolean mkdir()根据抽象路径名创建目录。
public String[] list()返回抽象路径名表示路径中的文件名和目录名。

2) 文件管理

在进行文件操作时,常需要知道一个关于文件的信息。Jave的File类提供了方法来操纵文件和获得一个文件的信息。另外,File类还可以对目录和文件进行删除、属性修改等管理工作

package com.ahuier.io;

import java.io.File;

public class FileTest3 {
public static void main(String[] args) {
/*
* 硬盘上存在目录:c:/abc/xyz/
* 创建目录 c:/abc/xyz/hello 即在上面的目录下继续创建 hello文件夹
*/
File file = new File("c:/abc/xyz/hello");
System.out.println(file.mkdir());
}
}
输出true,创建成功

【说明】注意用mkdir()方法,如果创建的目录上一级目录也不存在的话则创建不成功

package com.ahuier.io;

import java.io.File;

public class FileTest3 {
public static void main(String[] args) {
/*
* 硬盘上存在目录:c:/abc/
* 创建目录 c:/abc/xyz/hello 即在上面的目录下继续创建xyz/hello目录
* 一下代码输出false,创建不成功
*/
File file = new File("c:/abc/xyz/hello");
System.out.println(file.mkdir());
}
}
【说明】:如果想要跨级目录创建,则建议使用mkdirs()方法。
package com.ahuier.io;

import java.io.File;

public class FileTest3 {
public static void main(String[] args) {
/*
* 硬盘上存在目录:c:/
* 创建目录 c:/abc/xyz/hello 即在上面的目录下继续创建xyz/hello目录
* 使用mkdirs()创建,则创建成功,它会创建完整的目录结构
*/
File file = new File("c:/abc/xyz/hello");
System.out.println(file.mkdirs());

//判断file是否为一个目录或者文件 输出true和false
System.out.println(file.isDirectory());
System.out.println(file.isFile());
}
}


编译输出true,true,false

4. File 类定义了很多获取File对象标准属性的方法。例如getName()返回文件名,getParent()返回父目录名,exists()在文件存在的情况下返回true,反之返回false。然而File类是不对称的。说它不对称,意思是虽然存在允许验证一个简单文件对象属性的很多方法,但是没有相应的方法来改变这些属性

package com.ahuier.io;

import java.io.File;

public class FileTest4 {
public static void main(String[] args) {

/* 打印出目录 C:/Program Files/Common Files 下的所有文件名,注意只是打印出此目录下的文件名,此目录下的二级目录就无法打印了
法一:
File file = new File("C:/Program Files/Common Files");
String[] names = file.list();
for(String name : names){
System.out.println(name);
}
*/

//法二:
File file = new File("C:/Program Files/Common Files");

File[] files = file.listFiles();
for(File f : files){
System.out.println(f.getName());
}

}
}
编译执行结果:
Adobe

Adobe AIR

duowan

microsoft shared

Motorola Shared

Services

SpeechEngines

System

Tencent

TortoiseOverlays

5. File类中的常用方法

String getName()

String getPath()

String getAbsolutePath()

String getParent()

boolean renameTo( File newName)

long length()

boolean delete()

boolean mkdir()

String[] list()

boolean exists()

boolean canWrite()

boolean canRead()

boolean isFile()

boolean isDirectory()

6. 目录是一个包含其他文件和路径列表的File 类。当你创建一个File 对象且它是目录时,isDirectory() 方法返回ture。这种情况下,可以调用该对象的list()方法来提取该目录内部其他文件和目录的列表

package com.ahuier.io;

import java.io.File;
import java.io.IOException;

public class FileTest5 {
public static void main(String[] args) throws IOException {
File file = new File("c:/abc/xyz/hello/");
file.mkdirs();
File file2 = new File(file, "abc.txt");
file2.createNewFile();
file2.delete();
}
}


7.  在一个目录下有几十个文件,有些是以java文件,有些是txt文件,然后找出所有的java文件和txt文件

法一:先获取目录下是所有文件的字符串数组,然后遍历数组,找出以java文件或者txt文件

package com.ahuier.io;

import java.io.File;

public class FileTest6 {
public static void main(String[] args) {
File file = new File("C:/abc/xyz/hello");
String[] names = file.list();
for(String name : names){

//判断是否名字是以.java结尾的
if(name.endsWith(".java"))
System.out.println(name);
}
}
}
编译执行结果;
abc - 副本 (2).java

abc - 副本 (3).java

abc - 副本 (4).java

abc - 副本 (5).java

abc - 副本 (6).java

abc - 副本 (7).java

abc - 副本 (8).java

abc - 副本.java

abc.java

【说明】:判断是否以.java结尾,有些人可能会使用这种方式:if(name.lastIndexOf(".java") != -1) 如果 != -1 表示字符串从后往前找,找到以.java文件,但是这种写法不好,如果是这种表达式也是符合结果的:"aa.javafate.txt"但是它是属于txt文件,所以不符合逻辑

法二:

查看JDK 文档中的FilenameFilter接口,这是一个接口

boolean accept(File dir, String name)

    Tests if a specified file should be included in a file list. 

    Returns: true if and only if the name should be included in the file list; false otherwise.

    [测试指定文件是否被包含与指定的列表里面,如果是则返回真,如果否,则返回假]

查看File类中的方法:public String[] list(FilenameFilter filter),这个方法表示接受一个实现FilenameFilter接口的类的实例,然后重写accept()方法,在这个方法里面写期望什么样的文件包含再返回的数组里面即可。

1) 使用FilenameFilter

(1) 希望能够限制由list()方法返回的文件数目,使它仅返回那些与一定的文件名方式或者过滤(filter)相匹配的文件。为达到这样的目的,必须使用list()的第二种形式(方法重载): 

    String[] list(FilenameFilter FFObj)

    该形式中,FFObj是一个实现FilenameFilter接口的类的对象

2) FilenameFilter仅定义了一个方法,accept()。该方法被列表中的每个文件调用一次。它的通常形式如下:

   boolean accept(File directory, String filename)

4) 当被directory 指定的目录中的文件(也就是说,那些与filename 参数匹配的文件)包含在列表中时,accept()方法返回true ,当这些文件没有包括在列表中时,accept()返回false

package com.ahuier.io;

import java.io.File;
import java.io.FilenameFilter;

public class FileTest7 {
public static void main(String[] args) {
File file = new File("C:/abc/xyz/hello");
String[] names = file.list(new FilenameFilter() {

//这个方法有两个参数,第一参数表示带测试的文件所对应的目录,第二参数表示待测试的文件名本身,我们只用到name
@Override
public boolean accept(File dir, String name) {
if(name.endsWith(".java")){
return true;
}
return false;
}
});
for(String name : names){
System.out.println(name);
}
}

}
编译执行结果:
abc - 副本 (2).java

abc - 副本 (3).java

abc - 副本 (4).java

abc - 副本 (5).java

abc - 副本 (6).java

abc - 副本 (7).java

abc - 副本 (8).java

abc - 副本.java

abc.java

【说明】:其实这个程序就用到了一种策略模式,它就表示什么样的文件可以包含进去,什么样的文件不能包含进去。通过accept()决定。

8. 除了上述的一种String[] list();方式之外,还有一种是以listFile()方法,这种方式与上述类似。[这里就不做代码演示了]

1) listFiles()方法

File[] listFiles()

File[] listFiles(FilenameFilter FFObj)

File[] listFiles(FileFilter FObj)

    上述三种形式以File对象数组的形式返回文件列表,而不是用字符串形式返回。第一种形式返回所有的文件,第二种形式返回满足指定FilenameFilter接口的文件。除了返回一个File对象数组,这两个listFiles()方法就像list()方法一样工作,第三种listFiles()形式返回满足指定FileFilter的路径名的文件。FileFilter只定义了一个accept()方法,该方法被列表中的每个文件调用一次。

它的通常形式如下:

boolean accept(File path)

如果文件被包括在列表中(即与path参数匹配的文件),accept()方法返回true,如果不被包括,则返回false。

9. 在上一讲中提供的不同系统之间的路径分隔符问题,这边可以用Java提供的 separator() 表示路径分隔符。

package com.ahuier.io;

import java.io.File;
import java.io.IOException;

public class FileTest8 {
public static void main(String[] args) throws IOException {
File file = new File("c:" + File.separator + "hello.txt");
file.createNewFile();
}
}
表示在C盘下创建hello.txt文件。

【注意】:这边如果程序这样写,研究一下会变成什么样呢?

package com.ahuier.io;

import java.io.File;
import java.io.IOException;

public class FileTest8 {
public static void main(String[] args) throws IOException {

File file = new File(File.separator);
File file2 = new File(file, "test.txt");
System.out.println(file2.createNewFile());
}
}编译结果输出true,同时在D盘生成一个test.txt文件。
所以如果单纯直接用File.separator表示,则会在.class文件所在的盘符底下的根目录生成文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: