Java文件IO操作应该抛弃File拥抱Paths和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){
        }
        try (Stream<Path> stream = Files.list(Paths.get("C:/"))){
            Iterator<Path> ite = stream.iterator();
            while(ite.hasNext()){
                Path pp = ite.next();
                System.out.println(pp.getFileName());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用: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;
        }
    }
来一个实际例子:
    public static void main(String[] args) throws IOException {
        Path startingDir = Paths.get("F:\\upload\\images");    // F:\\upload\\images\\2\\20141206
        List<Path> result = new LinkedList<Path>();
        Files.walkFileTree(startingDir, new FindJavaVisitor(result));
        System.out.println("result.size()=" + result.size()); 
        System.out.println("done.");
    }
    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){
            String filePath = file.toFile().getAbsolutePath();
            if(filePath.matches(".*_[1|2]{1}\\.(?i)(jpg|jpeg|gif|bmp|png)")){
                try {
                    Files.deleteIfExists(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
              result.add(file.getFileName());
            } return FileVisitResult.CONTINUE;
        }
    }
将目录下面所有符合条件的图片删除掉:filePath.matches(".*_[1|2]{1}\\.(?i)(jpg|jpeg|gif|bmp|png)")
    public static void main(String[] args) throws IOException {
        Path startingDir = Paths.get("F:\\111111\\upload\\images");    // F:\111111\\upload\\images\\2\\20141206
        List<Path> result = new LinkedList<Path>();
        Files.walkFileTree(startingDir, new FindJavaVisitor(result));
        System.out.println("result.size()=" + result.size()); 
        System.out.println("done.");
    }
    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){
            String filePath = file.toFile().getAbsolutePath();
            int width = 224;
            int height = 300;
            StringUtils.substringBeforeLast(filePath, ".");
            String newPath = StringUtils.substringBeforeLast(filePath, ".") + "_1."
                                            + StringUtils.substringAfterLast(filePath, ".");
            try {
                ImageUtil.zoomImage(filePath, newPath, width, height);
            } catch (IOException e) {
                e.printStackTrace();
                return FileVisitResult.CONTINUE;
            }
            result.add(file.getFileName());
            return FileVisitResult.CONTINUE;
        }
    }
为目录下的所有图片生成指定大小的缩略图。a.jpg 则生成 a_1.jpg
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 的文档。
一个实际例子:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; public class StringTools {
public static void main(String[] args) {
try {
BufferedReader reader = Files.newBufferedReader(Paths.get("C:\\Members.sql"), StandardCharsets.UTF_8);
BufferedWriter writer = Files.newBufferedWriter(Paths.get("C:\\Members3.txt"), StandardCharsets.UTF_8); String str = null;
while ((str = reader.readLine()) != null) {
if (str != null && str.indexOf(", CAST(0x") != -1 && str.indexOf("AS DateTime)") != -1) {
String newStr = str.substring(0, str.indexOf(", CAST(0x")) + ")";
writer.write(newStr);
writer.newLine();
}
}
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
场景是,sql server导出数据时,会将 datatime 导成16进制的binary格式,形如:, CAST(0x0000A2A500FC2E4F AS DateTime))
所以上面的程序是将最后一个 datatime 字段导出的 , CAST(0x0000A2A500FC2E4F AS DateTime) 删除掉,生成新的不含有datetime字段值的sql 脚本。用来导入到mysql中。
做到半途,其实有更好的方法,使用sql yog可以很灵活的将sql server中的表以及数据导入到mysql中。使用sql server自带的导出数据的功能,反而不好处理。
Java文件IO操作应该抛弃File拥抱Paths和Files的更多相关文章
- Java文件IO操作应该抛弃File拥抱Path和Files
		
Java7中文件IO发生了很大的变化,专门引入了很多新的类: import java.nio.file.DirectoryStream;import java.nio.file.FileSystem; ...
 - java文件IO操作
		
package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream ...
 - Java 文件 IO  操作
		
window 路径分割符: \ 表示 windows 系统文件目录分割符 java 代码在 windows 下写某个文件的话需要下面的方式 D:\\soft\\sdclass.txt 其中一个单斜杠 ...
 - java安全编码指南之:文件IO操作
		
目录 简介 创建文件的时候指定合适的权限 注意检查文件操作的返回值 删除使用过后的临时文件 释放不再被使用的资源 注意Buffer的安全性 注意 Process 的标准输入输出 InputStream ...
 - 文件IO操作
		
前言 本文介绍使用java进行简单的文件IO操作. 操作步骤 - 读文件 1. 定义一个Scanner对象 2. 调用该对象的input函数族进行文件读取 (参见下面代码) 3. 关闭输入流 说明:其 ...
 - Java基础-IO流对象之File类
		
Java基础-IO流对象之File类 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.IO技术概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下 ...
 - Java学习---IO操作
		
基础知识 1.文件操作 Java语言统一将每个文件都视为一个顺序字节流.每个文件或者结束于一个文件结束标志,或者根据系统维护管理数据中所纪录的具体字节数来终止.当一个文件打开时,一个对象就被创建,同时 ...
 - 1.5 JAVA的IO操作
		
1.5 JAVA的IO操作 参考链接:https://www.runoob.com/java/java-files-io.html 一.JAVA的IO操作 由于JAVA引用外界的数据,或是将自身的数据 ...
 - Java - 文件(IO流)
		
Java - 文件 (IO) 流的分类: > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter ...
 
随机推荐
- Linux - Ubuntu下JDK配置
			
系统版本: ubuntu 14.04 x64JDK版本: jdk-8u60-linux-x64 1.查看系统位数,输入以下命令即可 getconf LONG_BIT 2.下载对应的JDK文件,我这里下 ...
 - 网狐6603棋牌游戏源码.rar
			
网狐6603棋牌游戏源码.rar http://pan.baidu.com/s/1dFgGNq5 网络收集仅供学习,下载后请务必在24小时内删除! 以上是原vc6.0源码,下载后使用vs2015编译, ...
 - asp.net学习之Repeater控件
			
asp.net学习之Repeater控件 文章摘自:http://www.cnblogs.com/shipfi/archive/2009/10/19/1585703.html Repeater控件和D ...
 - RSA密钥——JAVA与C#的区别和联系
			
PS:好久没写博了,最近在考虑以后的事情,而且手上杂事也比较多,终于得空来写两篇. 首先感谢:http://www.codeproject.com/Articles/25487/Cryptogra ...
 - Linux服务器时间同步方法
			
一般稍微大点的项目都会部署到好几台服务器做集群,同一个应用可能部署到几台服务器上,而处理业务中必须让不同的服务器上时间保持一致,这就需要进行服务器间的时间同步.我的做法是: 1,选择其中一台对外网开放 ...
 - spring事件通知机制详解
			
优势 解耦 对同一种事件有多种处理方式 不干扰主线(main line) 起源 要讲spring的事件通知机制,就要先了解一下spring中的这些接口和抽象类: ApplicationEventPub ...
 - Linux Shell系列教程之(十七) Shell文件包含
			
本文是Linux Shell系列教程的第(十七)篇,更多Linux Shell教程请看:Linux Shell系列教程 通过文件包含,可以引用其他文件的内容,也可以将复杂内容分开,使程序结构更加清晰. ...
 - ahjesus 获取当前方法被调用执行的具体位置,包括命名空间和方法
			
MethodBase method = ).GetMethod(); string ahjesus = method.ReflectedType.FullName + "." + ...
 - C#常用集合的使用(转载)
			
大多数集合都在System.Collections,System.Collections.Generic两个命名空间.其中System.Collections.Generic专门用于泛型集合. 针对特 ...
 - C# 分层     三层架构
			
Hello! 三层架构↓↓↓↓↓↓ 三层架构分为:表现层(UI(User Interface)).业务逻辑层(BLL(Business Logic Layer)).数据访问层(DAL(Data Acc ...