File是基于磁盘操作的I/O,Java多数IO都是实行流式操作,但是File不是,它不会读取文件信息或者向文件存储,它是直接处理文件的,它不会读取文件信息或者向文件存储,File对象可以用来获取或处理与磁盘文件相关的信息,例如权限,时间,日期和目录路径。File类的名字比较欺骗性,它其实并不仅仅代表一个特定文件名字,也可以代表文件目录下一系列文件名,用File存储数据存在很大的安全性,但是文件仍是我们存储数据以及共享数据的主要工具。
下面我们来解读File类在Java中的运用方式。
首先,我们来看下File的构造函数:
1. public File(String pathname)// pathname是文件的路径名以及文件名
2. public File(String parent, String child)// parent代表父类文件路径以及文件名,child代表子类文件路径以及文件名
3. public File(File parent, String child)//parent代表父类文件,child代表子类文件名
4 .public File(URI uri) //通过远程地址创建File对象
根据上面的构造函数,我们来用实例说明一下
File file1=new File("D:\\file1.txt");//绝对路径保证我们能找到文件 File file2=new File("D:\\","file1.txt"); File file3=new File("D:\\"); File file4=new File(file3,"file1.txt");
怎么读取文件的信息?我们知道Java是面向对象的,因此我们需要将文件转换为对象(具体怎么讲文件转换为对象不考虑),这样我们就可以通过操作对象来获取文件的信息。上面file1代表我们将D盘下文件file1.txt转化为File对象,file2与file1的构造函数区别在于我们把文件路径分割为两个部分,两个部分存在父子关系。file4 的构造函数代表着父类是一个file对象file3,实际上上面前3个都是将file1.txt这个文件构造为File对象,这样我们就可以通过File对象的方法获取我们需要的信息以及进行一系列操作。
注意:Java 能正确处理UNIX和Windows/DOS约定路径分隔符。如果在Windows版本的Java下用斜线(/),路径处理依然正确。记住,如果你用Windows使用反斜线(\)的约定,你需要在字符串内使用它的转义序列.
有很多人在这里会有疑问,我上面建的File实例都是用绝对路径,那么如果用相对路径,怎么建,文件放在哪?根据File JDK文档说明,java.io包中所有类,这个基地址由user.dir这个属性制定,也叫当前目录。如下代码:
System.out.println(System.getProperty("user.dir"));
所以如果想根据相对路径创建File对象,首先要把你要创建File的文件放到你代码的相对路径下,即上面代码查看的结果,然后创建File对象实例
其次,我们来看看File对象的方法:
1.getName()返回值 String
获取File对象文件名,如果File对象是文件夹,则获取文件夹名称,是文件则获取文件名称。源码也很简单,就是获取最后一个分隔符,然后字符串截取。
public String getName() { int index = path.lastIndexOf(separatorChar); if (index < prefixLength) return path.substring(prefixLength); return path.substring(index + 1); }
2.getParent()返回值 String
获取当前File的 父类文件名,当然这里可能不存在父类文件夹,即我们创建File对象用相对路径创建,很多人会疑惑,相对路径至少也是存储在代码根目录下的,为什么不会获取父类文件夹,那我们来看看源码你就清楚了,源码是直接从创建File对象是给定的路径截取父类文件名,如果给定的路径用相对路径,就不会获取父类文件。
public String getParent() { int index = path.lastIndexOf(separatorChar); if (index < prefixLength) { if ((prefixLength > 0) && (path.length() > prefixLength)) return path.substring(0, prefixLength); return null; } return path.substring(0, index); }
3.getParentFile()返回值 File
获取父类File对象实例,从源码可以看出如果调用此方法的File在构造时,传递的参数存在父类文件夹,则是可以获取的。
public File getParentFile() { String p = this.getParent();//直接调用获取父类路径方法 if (p == null) return null; return new File(p, this.prefixLength); }
4.getPath() 返回值 String
返回当前File对象实例的路径字符串,创建时File时传递的值是啥,返回的就是啥。
public String getPath() { return path; }
5.isAbsolute() 返回值 boolean
判断此File实例是不是绝对路径创建实例。
public boolean isAbsolute() { return fs.isAbsolute(this); }
6.getAbsolutePath() 返回值 String
获取此File实例的绝对路径字符串,不管File实例是已绝对路径或者相对路径创建。
public String getAbsolutePath() { return fs.resolve(this); }
7.getAbsoluteFile() 返回值 File
将File实例转化为绝对路径创建的File实例,对相对路径创建的File起作用,绝对路径创建的没变化。
public File getAbsoluteFile() { String absPath = getAbsolutePath(); return new File(absPath, fs.prefixLength(absPath)); }
8.getCanonicalPath() 返回值 String
返回此抽象路径名的规范路径名字符串。
规范路径名是绝对路径名,并且是惟一的。规范路径名的准确定义与系统有关。如有必要,此方法首先将路径名转换为绝对路径名,这与调用 getAbsolutePath() 方法的效果一样,然后用与系统相关的方式将它映射到其惟一路径名。这通常涉及到从路径名中移除多余的名称(比如 "." 和 "..")、解析符号连接(对于 UNIX 平台),以及将驱动器号转换为标准大小写形式(对于 Microsoft Windows 平台)。
每个表示现存文件或目录的路径名都有一个惟一的规范形式。每个表示不存在文件或目录的路径名也有一个惟一的规范形式。不存在文件或目录路径名的规范形式可能不同于创建文件或目录之后同一路径名的规范形式。同样,现存文件或目录路径名的规范形式可能不同于删除文件或目录之后同一路径名的规范形式。
返回:
规范路径名字符串,它与此抽象路径名表示相同的文件或目录
public String getCanonicalPath() throws IOException { if (isInvalid()) { throw new IOException("Invalid file path"); } return fs.canonicalize(fs.resolve(this)); }
这个不是很好理解但是我们可以用例子对比一下,有经验的程序员用过相对路径,应该都清楚../test2.txt中的..在相对路径代表上一级目录
File file4=new File("test2.txt"); File file5=new File("../test2.txt"); System.out.println(file4.getAbsolutePath()+"------"+file5.getAbsolutePath()); System.out.println(file4.getCanonicalPath()+"------"+file5.getCanonicalPath()); -------打印结果------ F:\guoxiangworkspace\Socket\test2.txt------F:\guoxiangworkspace\Socket\..\test2.txt F:\guoxiangworkspace\Socket\test2.txt------F:\guoxiangworkspace\test2.txt
可以看出getAbsolutePath将..也打印出来了,实际我的标准的路径是F:\guoxiangworkspace\test2.txt,而getCanonicalPath()就是标准化路径,并不是根据创建的抽象路径直接打印,是经过处理的。
9.getCanonicalFile() 返回值 File
同上,只是返回File实例。
public File getCanonicalFile() throws IOException { String canonPath = getCanonicalPath(); return new File(canonPath, fs.prefixLength(canonPath)); }
10.toURI() 返回值 URI
返回创建File实例抽象路径的URI实例,什么是URI有兴趣的可以百度
http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html
http://www.cnblogs.com/hust-ghtao/p/4724885.html 附上两篇文章
public URI toURI() { try { File f = getAbsoluteFile(); String sp = slashify(f.getPath(), f.isDirectory()); if (sp.startsWith("//")) sp = "//" + sp; return new URI("file", null, sp, null); } catch (URISyntaxException x) { throw new Error(x); // Can‘t happen } }
11.canRead() 返回值 boolean
判断该File实例是否可以读取,简单的说就是你的程序如果想读取File 文件的内容,能不能读。如果读取权限被限制,则返回false。
public boolean canRead() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return false; } return fs.checkAccess(this, FileSystem.ACCESS_READ); }
12.canWrite() 返回值 boolean
同上,判断该文件是否可以往内写数据。
public boolean canWrite() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(path); } if (isInvalid()) { return false; } return fs.checkAccess(this, FileSystem.ACCESS_WRITE); }
13.exists() 返回值 boolean
判断该File实例创建时,传递的抽象路径所代表的文件或者文件夹是否真的存在。
public boolean exists() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return false; } return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0); }
14. isDirectory()返回值 boolean
判断该File实例代表的是否是文件夹。
public boolean isDirectory() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return false; } return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY) != 0); }
15.isFile()返回值 boolean
判断该File实例代表的是否是文件。
public boolean isFile() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return false; } return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0); }
16.isHidden() 返回值 boolean
判断是否是隐藏文件。
public boolean isHidden() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return false; } return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0); }
17.lastModified() 返回值 long
返回最后一次该File实例代表的文件或者文件夹修改时间。返回的long类型,转换为Data,Date date = new Date(long类型时间);
public long lastModified() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return 0L; } return fs.getLastModifiedTime(this); }
18.length() 返回值 long
返回文件内容的长度,以字节为单位。
public long length() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return 0L; } return fs.getLength(this); }
19.createNewFile()返回值 boolean
根据File实例的逻辑路径创建新文件,并返回创建结果,如果文件已经存在,则返回false。
使用: File file = new File("D:/test/1.txt"); boolean res = file.createNewFile(); if(!res)System.out.println("创建失败!");
如果D:/test 目录下没有 1.txt文件,则创建该文件;如果没有test目录,直接抛出异常,如果1.txt已经存在,那么文件创建失败。 可以得知,createNewFile() 方法,根据抽象路径创建一个新的空文件,当抽象路径制定的文件存在时,创建失败。
public boolean createNewFile() throws IOException { SecurityManager security = System.getSecurityManager(); if (security != null) security.checkWrite(path); if (isInvalid()) { throw new IOException("Invalid file path"); } return fs.createFileExclusively(path); }
与之相似的方法createTempFile() 方法
该方法有两种调用方式: createTempFile(String prefix, String suffix); 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。 createTempFile(String prefix, String suffix, File directory); 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
实例:
public class TestFile2 { public static void main(String[] args) { File f1 = new File("D:\"); File f2 = null; try { f2 = File.createTempFile("abc", ".txt", f1); System.out.println(f2.getName()); } catch (IOException e) { e.printStackTrace(); } } }
打印结果abc807062783757555654.txt
看源码:TempDirectory.generateFile(prefix, suffix, tmpdir)这个函数会生成19位数字追加在前缀。
public static File createTempFile(String prefix, String suffix, File directory) throws IOException { if (prefix.length() < 3) throw new IllegalArgumentException("Prefix string too short"); if (suffix == null) suffix = ".tmp"; File tmpdir = (directory != null) ? directory : TempDirectory.location(); SecurityManager sm = System.getSecurityManager(); File f; do { // f = TempDirectory.generateFile(prefix, suffix, tmpdir); if (sm != null) { try { sm.checkWrite(f.getPath()); } catch (SecurityException se) { // don‘t reveal temporary directory location if (directory == null) throw new SecurityException("Unable to create temporary file"); throw se; } } } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0); if (!fs.createFileExclusively(f.getPath())) throw new IOException("Unable to create temporary file"); return f; }
20.delete()返回值 boolean
根据File实例创建时传递的抽象路劲进行删除,如果文件存在,则删除并返回true,如果不存在或者限制删除,则返回false。
public boolean delete() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkDelete(path); } if (isInvalid()) { return false; } return fs.delete(this); }
21.deleteOnExit() 无返回值
此方法要求将表示此抽象路径名的文件或目录在虚拟机终止时被删除。
public void deleteOnExit() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkDelete(path); } if (isInvalid()) { return; } DeleteOnExitHook.add(path); }
22.list() 返回String[]
返回调用该方法File实例抽象路径名的目录中的文件和目录的字符串数组,即该文件夹下包含的所有文件或者文件夹(不包含文件夹下的子文件)名称组成的数组。
public String[] list() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } if (isInvalid()) { return null; } return fs.list(this); }
23.list(FilenameFilter filter) 返回String[]
相比较上面的方法,多出一个FilenameFilter filter参数,从名字就可以分析出,这个参数是具有过滤作用的。我们习惯用匿名内部类来覆盖FilenameFilter 类方法进行过滤。实例如下
import java.io.File; import java.io.FilenameFilter; public class FileDemo { public static void main(String[] args) { File f = null; File[] paths; try{ f = new File("D:/test"); FilenameFilter fileNameFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { if(name.lastIndexOf(‘.‘)>0) { int lastIndex = name.lastIndexOf(‘.‘); String str = name.substring(lastIndex) if(str.equals(".txt")) { return true; } } return false; } }; paths = f.listFiles(fileNameFilter); for(File path:paths) { System.out.println(path); } }catch(Exception e){ e.printStackTrace(); } }}
public String[] list(FilenameFilter filter) { String names[] = list(); if ((names == null) || (filter == null)) { return names; } List<String> v = new ArrayList<>(); for (int i = 0 ; i < names.length ; i++) { if (filter.accept(this, names[i])) { v.add(names[i]); } } return v.toArray(new String[v.size()]); }
24.listFiles() 返回值File[]
此方法用于返回调用该方法的File实例下包含的文件以及文件夹的File实例数组。
public File[] listFiles() { String[] ss = list(); if (ss == null) return null; int n = ss.length; File[] fs = new File[n]; for (int i = 0; i < n; i++) { fs[i] = new File(ss[i], this); } return fs; }
25.listFiles(FilenameFilter filter) 返回值File[]
同list(FilenameFilter filter)用法相同,先获取调用该方法File下所有文件以及文件夹名称,然后根据过滤条件进行过滤,再将过滤后的得到的文件名数组实例化为File[]数组。
public File[] listFiles(FilenameFilter filter) { String ss[] = list(); if (ss == null) return null; ArrayList<File> files = new ArrayList<>(); for (String s : ss) if ((filter == null) || filter.accept(this, s)) files.add(new File(s, this)); return files.toArray(new File[files.size()]); }
26.listFiles(FileFilter filter) 返回值File[]
同上,但是过滤器类型不同,FilenameFilter只能针对文件名为条件,而FileFilter可以通过调用File方法来返回true或者false来过滤。
如下实例:
import java.io.File; import java.io.FileFilter; public class FileDemo { public static void main(String[] args) { File f = null; File[] paths; try{ f = new File("D:/test"); FileFilter filter = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } }; paths = f.listFiles(filter); for(File path:paths) { System.out.println(path); } }catch(Exception e){ e.printStackTrace(); } }}
源代码:
public File[] listFiles(FileFilter filter) { String ss[] = list(); if (ss == null) return null; ArrayList<File> files = new ArrayList<>(); for (String s : ss) { File f = new File(s, this); if ((filter == null) || filter.accept(f)) files.add(f); } return files.toArray(new File[files.size()]); }
27.mkdir()与mkdirs() 返回值boolean
两个方法都是用来创建以抽象路径为名的文件夹,区别在于madir()只能对已经存在的文件夹建立单层子文件夹,如果建立多层嵌套的文件夹则用mkdirs(),包含在抽象路径下的文件夹必须都不能存在,否则则不能建立嵌套文件夹,如果建立成功返回true。
public boolean mkdir() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(path); } if (isInvalid()) { return false; } return fs.createDirectory(this); } public boolean mkdirs() { if (exists()) { return false; } if (mkdir()) { return true; } File canonFile = null; try { canonFile = getCanonicalFile(); } catch (IOException e) { return false; } File parent = canonFile.getParentFile(); return (parent != null && (parent.mkdirs() || parent.exists()) && canonFile.mkdir()); }
28.renameTo(File dest) 返回值boolean
对File实例代表的文件或者文件夹进行重新命名,可用来进行移动文件功能。
存在四种情况会移动失败:第一,file实例代表的源文件不存在,第二,dir代表的文件不存在,第三,两者都不存在,还有一种是硬盘格式不同也会导致移动失败,有人测试过。
实例如下:
public boolean copyFiles(String srcPath,String destPath){ File file = new File(srcPath); File dir = new File(destPath); boolean success = file.renameTo(new File(dir,file.getName())); return success; }
源代码:
public boolean renameTo(File dest) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(path); security.checkWrite(dest.path); } if (dest == null) { throw new NullPointerException(); } if (this.isInvalid() || dest.isInvalid()) { return false; } return fs.rename(this, dest); }
29.剩下的一些方法大多跟设置文件属性值有关,就不详细列举了,只大概写一下
setLastModified(long time) 设置文件最后一次修改时间。
setReadOnly() 设置文件或目录只允许读操作。
setWritable(boolean writable, boolean ownerOnly)
- writable --如果为true,允许写访问权限;如果为false,写访问权限是不允许的。
- ownerOnly --如果为true,则写访问权限仅适用于所有者,否则它适用于所有人。
setWritable(boolean writable)
- writable --如果为true,允许写访问权限;如果为false,写访问权限是不允许的。
setReadable(boolean readable, boolean ownerOnly)
- readable -- true时是设置访问在未经许可允许读操作。
- ownerOnly -- 只有读权限适用于业主的读取权限,如果ownerOnly设置为true;否则返回false。
setReadable(boolean readable)
- readable -- true时是设置访问在未经许可允许读操作。
setExecutable(boolean executable, boolean ownerOnly)
- executable -- 为true时设置访问权限,允许执行的操作,假否认执行操作。
- ownerOnly -- 为true时设置执行权限只对主人的执行权限为ture; 否则,它适用于每一个人。
setExecutable(boolean executable)
- executable -- 设置访问权限为true,允许执行的操作,否则执行操作为false。
canExecute()
此方法返回布尔值-true,如果指定的文件存在的路径名和文件允许应用程序读取。
listRoots()
该方法返回指示可用的文件系统的根文件对象的数组。如果不能确定该组的根该方法返回null。
getTotalSpace()
该方法返回指定的文件夹或者文件内容大小。
getFreeSpace()
返回未分配空间大小。
getUsableSpace()
该方法返回该分区上的可用的字节数
compareTo()
public int compareTo(File pathname)按字母顺序比较两个抽象路径名。此方法定义的顺序取决于底层系统。在 UNIX 系统上,比较路径名时,字母大小写通常很重要,而在 Microsoft Windows 系统上,这通常不重要。
以上基本是File这个类中的大部分函数,也许还存在函数方法我未列举出,如果我发现我会补充,有不足之处或者错误的地方,可以留言给我,我会修改,谢谢。