4.迭代目录中的文件
4.1迭代该目录下的文件,try语句可以保证目录流最后被正常关闭
/**
* 遍历本目录底下所有文件和文件夹
*/
public static void directoryStream(Path path){
try(DirectoryStream<Path> paths = Files.newDirectoryStream(path)){
Iterator<Path> iterator = paths.iterator();
while(iterator.hasNext())
System.out.println(iterator.next().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
4.2如果要遍历所有的子孙目录与文件,Files也提供了另外一个方法
/**
* 遍历所有子孙目录和文件
*/
public static void walkFileTree(final Path path){
try {
Path path1 = Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println(dir.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException{
System.out.println(file.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
5.内存映射文件
利用虚拟内存将文件或文件的一部分映射到内存,没有磁盘的io操作,这比传统的文件操作速度更快。nio中有一个通道概念,从一个文件中获得通道,可以利用这个通道做文件操作。
下面是一个实例demo:
//获得一个文件通道
FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)
//文件的字节大小
long size = channel.size();
//做内存映射操作,决定文件的读取方式,以及文件映射的范围
MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
//获取映射后的字节
for (int i = 0; i < size; i++)
map.get(i);
它跟传统的文件流操作有对比试验
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;
/**
* 介绍 内存映射文件 nio ,且与其他io进行性能测试
* Created by panqian on 2017/1/18.
*/
public class FileChannel_1 {
public static void main(String[] args) {
Path path = Paths.get("农门长姐.txt");
FileChannel_1.fileInputStreamRead(path);
FileChannel_1.fileChannelMapRead(path);
FileChannel_1.fileBufferedInputStreamRead(path);
FileChannel_1.fileRandomAccessRead(path);
}
/**
* 文件通道(内存映射文件)
*
* @param path
*/
public static void fileChannelMapRead(Path path) {
System.out.println("fileChannelMapRead : ");
long start = System.currentTimeMillis();
if (path.toFile().exists()) {
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
long size = channel.size();
MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
for (int i = 0; i < size; i++)
map.get(i);
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("run " + (end - start) + " milliseconds");
}
/**
* 普通输入流
*
* @param path
*/
public static void fileInputStreamRead(Path path) {
System.out.println("fileInputStreamRead : ");
long start = System.currentTimeMillis();
if (path.toFile().exists()) {
try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) {
int c;
while ((c = inputStream.read()) != -1) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("run " + (end - start) + " milliseconds");
}
/**
* 带缓冲区的输入流
*
* @param path
*/
public static void fileBufferedInputStreamRead(Path path) {
System.out.println("fileBufferedInputStreamRead : ");
long start = System.currentTimeMillis();
if (path.toFile().exists()) {
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(path.toFile()))) {
int c;
while ((c = bufferedInputStream.read()) != -1) {
}
} catch (IOException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("run " + (end - start) + " milliseconds");
}
}
/**
* 随机访问文件(RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代)
*
* @param path
*/
public static void fileRandomAccessRead(Path path) {
System.out.println("fileRandomAccessRead : ");
long start = System.currentTimeMillis();
if (path.toFile().exists()) {
try (RandomAccessFile accessFile = new RandomAccessFile(path.toFile(), "r")) {
int c;
while ((c = accessFile.read()) != -1) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("run " + (end - start) + " milliseconds");
}
}
实验结果如下:可以看出,内存映射文件和带缓冲区的输入流读取速度都很快,而普通输入流和随机访问文件较慢,体现了nio的优势。
fileInputStreamRead :
run 6249 milliseconds
fileChannelMapRead :
run 9 milliseconds
fileBufferedInputStreamRead :
run 17 milliseconds
fileRandomAccessRead :
run 4503 milliseconds