在做java.io操作文件的时候,有一需求是:将给定目录路径下的所有文件、文件夹罗列出来。
这样就不可避免用到File
类中的listFiles()
方法,一开始想到的是用File类实例化一个对象,构造方法中给出初始的目录路径;然后通过.listFiles()
方法返回路径下的所有资源,用一个File[]
数组接收一下,之后遍历数组打印出来就可以了。话不多说上代码……
我们先看一下文档和源码中对方法的描述吧:
文档&源码
listFiles_methods.jpg这里一共有3个,两个重载,我们只看最上面的那个。
/**
* Returns an array of abstract pathnames denoting the files in the
* directory denoted by this abstract pathname.
*
* <p> If this abstract pathname does not denote a directory, then this
* method returns {@code null}. Otherwise an array of {@code File} objects
* is returned, one for each file or directory in the directory. Pathnames
* denoting the directory itself and the directory's parent directory are
* not included in the result. Each resulting abstract pathname is
* constructed from this abstract pathname using the {@link #File(File,
* String) File(File, String)} constructor. Therefore if this
* pathname is absolute then each resulting pathname is absolute; if this
* pathname is relative then each resulting pathname will be relative to
* the same directory.
*
* <p> There is no guarantee that the name strings in the resulting array
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
* <p> Note that the {@link java.nio.file.Files} class defines the {@link
* java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
* to open a directory and iterate over the names of the files in the
* directory. This may use less resources when working with very large
* directories.
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
* The array will be empty if the directory is empty. Returns
* {@code null} if this abstract pathname does not denote a
* directory, or if an I/O error occurs.
*
* @throws SecurityException
* If a security manager exists and its {@link
* SecurityManager#checkRead(String)} method denies read access to
* the directory
*
* @since 1.2
*/
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;
}
大致就是说,该方法返回一个抽象路径名数组,用来表示该路径名对应目录下的文件。
先来感受一下吧!
import java.io.*;
import java.util.*;
public class CopyFile {
public static void main(String[] args) {
File file = new File("c:/");
File[] dirs = file.listFiles();
for(File f: dirs) {
System.out.println(f.getAbsoluteFile());
}
}
}
运行结果
"C:\Program Files\Java\jdk1.8.0_172\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\lib\idea_rt.jar=56512:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_172\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\Practice20180728\out\production\Practice20180728" copy_file_demo.CopyFile
c:\$360Section
c:\$RECYCLE.BIN
c:\360Downloads
c:\360SANDBOX
c:\360WiFi
c:\BaiduNetdiskDownload
c:\Boot
c:\bootmgr
c:\BOOTSECT.BAK
c:\Documents and Settings
c:\Drivers
c:\GreenSoftWare
c:\JAVA_Learning
c:\java基础_代码笔记
c:\pagefile.sys
c:\Program Files
c:\Program Files (x86)
c:\ProgramData
c:\SUDIJ
c:\System Volume Information
c:\Users
c:\VPM
c:\Windows
Process finished with exit code 0
基本上c盘所有的文件和文件夹都显示出来了。
现在我又有个新的想法了,我想把这个返回的数组转换成List,该怎么做呢?至于为什么想转换成List,可能因为我想用迭代器遍历?或者仅仅是因为好奇?你管我呀!反正总有用到的时候。
查来查去,最终把目光锁定在了Arrays.asList()这个方法上,老规矩,先看文档,再看源码:
文档&源码
Arrays.asList().jpg/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
这是一个静态方法,基本上是和collection.toArray()互补使用的,这两个方法作为数组和集合类的桥梁,使用频率还是蛮高的。
贴代码:
package copy_file_demo;
import java.io.*;
import java.util.*;
public class CopyFile {
public static void main(String[] args) {
File file = new File("c:/");
// File[] dirs = file.listFiles();
List<File> arrDirs = Arrays.asList(file.listFiles());
Iterator iter = arrDirs.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
// for(File f: dirs) {
// System.out.println(f.getAbsoluteFile());
// }
}
}
运行结果
"C:\Program Files\Java\jdk1.8.0_172\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\lib\idea_rt.jar=56708:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_172\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\Practice20180728\out\production\Practice20180728" copy_file_demo.CopyFile
c:\$360Section
c:\$RECYCLE.BIN
c:\360Downloads
c:\360SANDBOX
c:\360WiFi
c:\BaiduNetdiskDownload
c:\Boot
c:\bootmgr
c:\BOOTSECT.BAK
c:\Documents and Settings
c:\Drivers
c:\GreenSoftWare
c:\JAVA_Learning
c:\java基础_代码笔记
c:\pagefile.sys
c:\Program Files
c:\Program Files (x86)
c:\ProgramData
c:\SUDIJ
c:\System Volume Information
c:\Users
c:\VPM
c:\Windows
Process finished with exit code 0
哇哈哈哈哈哈~完美! perfect!
不过要注意的是,List接收返回值后向下转型编译期间不会报错,一运行就会报错,我估计是因为本来返回值就是ArrayList类型,只不过用List接口引用了一下,把自己转为同类肯定会报错。这只是猜测,我也不知道具体原因是什么,这里做个记号,也恳请大神们不吝赐教,小的实在太菜。
同样有一个值得注意的问题,代码说话:
import java.util.*;
public class Main {
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6};
List arr = Arrays.asList(nums);
Iterator iter = arr.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
// System.out.println(arr);
}
}
这里做了个实验,把Arrays.asList()
的入参换成成员是Number
类型的数组(注意:collection
接口中不能放基本数据类型,所以尝试把int
、double
等数组放进去根本就是徒劳,不过可以转换成对应的包装类型后放进去。)一切相安无事:
"C:\Program Files\Java\jdk1.8.0_172\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\lib\idea_rt.jar=57150:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_172\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\test\out\production\test" Main
1
2
3
4
5
6
Process finished with exit code 0
可是一旦把List
改为ArrayList
,就会立马报错,这个还和前面的不一样,前面的例子在改用ArrayList
接收的时候并没有报错。总之,懂得还是太少,路漫漫其修远兮。
网友评论