Java文件IO操作应该抛弃File拥抱Path和Files

Java7中文件IO发生了很大的变化,专门引入了很多新的类:

import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;

......等等,来取代原来的基于java.io.File的文件IO操作方式.

1. Path就是取代File的

A Path represents a path that is hierarchical and composed of a sequence of directory and file name elements separated by a special separator or delimiter.

Path用于来表示文件路径和文件。可以有多种方法来构造一个Path对象来表示一个文件路径,或者一个文件:

1)首先是final类Paths的两个static方法,如何从一个路径字符串来构造Path对象:

        Path path = Paths.get("C:/", "Xmp");
        Path path2 = Paths.get("C:/Xmp");

        URI u = URI.create("file:///C:/Xmp/dd");
        Path p = Paths.get(u);

2)FileSystems构造:

Path path3 = FileSystems.getDefault().getPath("C:/", "access.log");

3)File和Path之间的转换,File和URI之间的转换:

        File file = new File("C:/my.ini");
        Path p1 = file.toPath();
        p1.toFile();
        file.toURI();

4)创建一个文件:

        Path target2 = Paths.get("C:\\mystuff.txt");
//      Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-rw-rw-");
//      FileAttribute<Set<PosixFilePermission>> attrs = PosixFilePermissions.asFileAttribute(perms);
        try {
            if(!Files.exists(target2))
                Files.createFile(target2);
        } catch (IOException e) {
            e.printStackTrace();
        }

windows下不支持PosixFilePermission来指定rwx权限。

5)Files.newBufferedReader读取文件:

        try {
//            Charset.forName("GBK")
            BufferedReader reader = Files.newBufferedReader(Paths.get("C:\\my.ini"), StandardCharsets.UTF_8);
            String str = null;
            while((str = reader.readLine()) != null){
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

可以看到使用 Files.newBufferedReader 远比原来的FileInputStream,然后BufferedReader包装,等操作简单的多了。

这里如果指定的字符编码不对,可能会抛出异常 MalformedInputException ,或者读取到了乱码:

java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at com.coin.Test.main(Test.java:79)

6)文件写操作:

        try {
            BufferedWriter writer = Files.newBufferedWriter(Paths.get("C:\\my2.ini"), StandardCharsets.UTF_8);
            writer.write("测试文件写操作");
            writer.flush();
            writer.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

7)遍历一个文件夹:

        Path dir = Paths.get("D:\\webworkspace");
        try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
            for(Path e : stream){
                System.out.println(e.getFileName());
            }
        }catch(IOException e){

        }

上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用:Files.walkFileTree

8)遍历整个文件目录:

    public static void main(String[] args) throws IOException{
        Path startingDir = Paths.get("C:\\apache-tomcat-8.0.21");
        List<Path> result = new LinkedList<Path>();
        Files.walkFileTree(startingDir, new FindJavaVisitor(result));
        System.out.println("result.size()=" + result.size());
    }

    private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
        private List<Path> result;
        public FindJavaVisitor(List<Path> result){
            this.result = result;
        }
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){
            if(file.toString().endsWith(".java")){
                result.add(file.getFileName());
            }
            return FileVisitResult.CONTINUE;
        }
    }

2. 强大的java.nio.file.Files

1)创建目录和文件:

        try {
            Files.createDirectories(Paths.get("C://TEST"));
            if(!Files.exists(Paths.get("C://TEST")))
                    Files.createFile(Paths.get("C://TEST/test.txt"));
//            Files.createDirectories(Paths.get("C://TEST/test2.txt"));
        } catch (IOException e) {
            e.printStackTrace();
        }

注意创建目录和文件Files.createDirectories 和 Files.createFile不能混用,必须先有目录,才能在目录中创建文件。

2)文件复制:

从文件复制到文件:Files.copy(Path source, Path target, CopyOption options);

从输入流复制到文件:Files.copy(InputStream in, Path target, CopyOption options);

从文件复制到输出流:Files.copy(Path source, OutputStream out);

        try {
            Files.createDirectories(Paths.get("C://TEST"));
            if(!Files.exists(Paths.get("C://TEST")))
                    Files.createFile(Paths.get("C://TEST/test.txt"));
//          Files.createDirectories(Paths.get("C://TEST/test2.txt"));
            Files.copy(Paths.get("C://my.ini"), System.out);
            Files.copy(Paths.get("C://my.ini"), Paths.get("C://my2.ini"), StandardCopyOption.REPLACE_EXISTING);
            Files.copy(System.in, Paths.get("C://my3.ini"), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }

3)遍历一个目录和文件夹上面已经介绍了:Files.newDirectoryStream , Files.walkFileTree

4)读取文件属性:

            Path zip = Paths.get(uri);
            System.out.println(Files.getLastModifiedTime(zip));
            System.out.println(Files.size(zip));
            System.out.println(Files.isSymbolicLink(zip));
            System.out.println(Files.isDirectory(zip));
            System.out.println(Files.readAttributes(zip, "*"));

5)读取和设置文件权限:

            Path profile = Paths.get("/home/digdeep/.profile");
            PosixFileAttributes attrs = Files.readAttributes(profile, PosixFileAttributes.class);// 读取文件的权限
            Set<PosixFilePermission> posixPermissions = attrs.permissions();
            posixPermissions.clear();
            String owner = attrs.owner().getName();
            String perms = PosixFilePermissions.toString(posixPermissions);
            System.out.format("%s %s%n", owner, perms);

            posixPermissions.add(PosixFilePermission.OWNER_READ);
            posixPermissions.add(PosixFilePermission.GROUP_READ);
            posixPermissions.add(PosixFilePermission.OTHERS_READ);
            posixPermissions.add(PosixFilePermission.OWNER_WRITE);

            Files.setPosixFilePermissions(profile, posixPermissions);    // 设置文件的权限

Files类简直强大的一塌糊涂,几乎所有文件和目录的相关属性,操作都有想要的api来支持。这里懒得再继续介绍了,详细参见 jdk8 的文档。

时间: 2024-10-11 12:03:18

Java文件IO操作应该抛弃File拥抱Path和Files的相关文章

java文件io操作

FileReader fr=new FileReader("D:\\Demo.txt"); char[] ch=new char[2]; int len=0; while((len=fr.read(ch))!=-1) { System.out.print(new String(ch, 0, len)); } FileReader fr=new FileReader("D:\\Demo.txt"); int cl=0; while((cl=fr.read())!=-1

Java 文件写操作

在进行文件写操作的时候,有两种操作方方式.一个是连续写,一个是覆盖式写. 代码如下: import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; // text:要写入的内容:isAppend:写入方式,true为连续写,false为覆盖式写入. public void write(String text

文件IO操作

前言 本文介绍使用java进行简单的文件IO操作. 操作步骤 - 读文件 1. 定义一个Scanner对象 2. 调用该对象的input函数族进行文件读取 (参见下面代码) 3. 关闭输入流 说明:其实和标准输入没什么不同.唯一要注意的区别就是 1 中Scanner构造函数的参数要是路径类型那么才是读文件,否则就是读字符串.(参考下面代码注释部分) 示例代码 1 package test; 2 3 import java.io.IOException; 4 import java.nio.fil

Linux学习记录--文件IO操作相关系统编程

文件IO操作相关系统编程 这里主要说两套IO操作接口,分别是: POSIX标准 read|write接口,函数定义在#include<unistd.h> ISO C标准 fread|fwrite接口,函数定义在#include<stdio.h> 有书上说POSIX标准与ISO C标准的区别在于文件读写是否带缓冲区,我则不是很认同,因此POSIX标准下的IO操作也是带缓冲区的,至于这两个标准下的IO性能谁更加好则不一定,因为这和缓冲区的大小,以及用户逻辑有很大关系. POSIX标准

imx6用文件io操作gpio

具体请参考: http://blog.csdn.net/u014213012/article/details/53140781 这里要注意的是: 要让linux支持文件io方式操作gpio,首先驱动必须得支持,也就是说设备树上必须先配置好gpio模式,然后参照以上链接去实现gpio操作 这里举例来说:hud项目中(imx6dl平台),有一个蓝牙电源的使能受GPIO1_IO30的控制,所以我们必须得在设备树上配置这个pad为GPIO模式 1.配置gpio模式 现在需要在设备树上配置GPIO1_IO

树莓派学习笔记——使用文件IO操作GPIO SysFs方式

0 前言 本文描述如果通过文件IO sysfs方式控制树莓派 GPIO端口.通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入. Linux学习可从应用出发,先不纠结Linux驱动编写,先把Linux给玩起来. [相同与不同] 本文和[EasyARM

Java的IO操作---File类

目标 1)掌握File类作用 2)可以使用file类中方法对文件进行读写操作. File类 唯一与文件有关的类.使用file类可进行创建或删除操作,要想使用File类,首先观察File类的构造方法. public File(String pathname);实例化File类的时候,必须设置好路径. 常量:: public staitc final String pathSeparator: 明明使用了static final定义的常量,这里为什么使用了小写方式.实际上这属于JAVA的历史遗留问题

java文件读写操作

Java IO系统里读写文件使用Reader和Writer两个抽象类,Reader中read()和close()方法都是抽象方法.Writer中 write(),flush()和close()方法为抽象方法.子类应该分别实现他们. Java IO已经为我们提供了三个方便的Reader的实现类,FileReader,InputStreamReader和BufferedReader.其中最重要的类是InputStreamReader, 它是字节转换为字符的桥梁.你可以在构造器重指定编码的方式,如果不

java文件读写操作类

借鉴了项目以前的文件写入功能,实现了对文件读写操作的封装 仅仅需要在读写方法传入路径即可(可以是绝对或相对路径) 以后使用时,可以在此基础上改进,比如: 写操作: 1,对java GUI中文本框中的内容进行捕获,放在txt文本文档中 2,对各种类型数据都以字符串的形式逐行写入 3,对全局数组的内容进行写入 读操作: 获取文件行数 对逐行字符串型数据进行类型转换,放入二维数组中 为后面算法处理提供入口,但是要小心的是:不可以将行数用全局变量做计数器,否则每次读入是全局变量累加出错,应重新开始读取