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的

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);    // 设置文件的权限
复制代码

你可能感兴趣的:(java)