基于java Files類(lèi)和Paths類(lèi)的用法(詳解)
Java7中文件IO發(fā)生了很大的變化,專門(mén)引入了很多新的類(lèi):
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;
......等等,來(lái)取代原來(lái)的基于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用于來(lái)表示文件路徑和文件。可以有多種方法來(lái)構(gòu)造一個(gè)Path對(duì)象來(lái)表示一個(gè)文件路徑,或者一個(gè)文件:
1)首先是final類(lèi)Paths的兩個(gè)static方法,如何從一個(gè)路徑字符串來(lái)構(gòu)造Path對(duì)象:
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構(gòu)造:
Path path3 = FileSystems.getDefault().getPath("C:/", "access.log");
3)File和Path之間的轉(zhuǎn)換,F(xiàn)ile和URI之間的轉(zhuǎn)換:
File file = new File("C:/my.ini");
Path p1 = file.toPath();
p1.toFile();
file.toURI();
4)創(chuàng)建一個(gè)文件:
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來(lái)指定rwx權(quán)限。
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 遠(yuǎn)比原來(lái)的FileInputStream,然后BufferedReader包裝,等操作簡(jiǎn)單的多了。
這里如果指定的字符編碼不對(duì),可能會(huì)拋出異常 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)文件寫(xiě)操作:
try {
BufferedWriter writer = Files.newBufferedWriter(Paths.get("C:\\my2.ini"), StandardCharsets.UTF_8);
writer.write("測(cè)試文件寫(xiě)操作");
writer.flush();
writer.close();
} catch (IOException e1) {
e1.printStackTrace();
}
7)遍歷一個(gè)文件夾:
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();
}
上面是遍歷單個(gè)目錄,它不會(huì)遍歷整個(gè)目錄。遍歷整個(gè)目錄需要使用:Files.walkFileTree
8)遍歷整個(gè)文件目錄:
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;
}
}
來(lái)一個(gè)實(shí)際例子:
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. 強(qiáng)大的java.nio.file.Files
1)創(chuàng)建目錄和文件:
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();
}
注意創(chuàng)建目錄和文件Files.createDirectories 和 Files.createFile不能混用,必須先有目錄,才能在目錄中創(chuàng)建文件。
2)文件復(fù)制:
從文件復(fù)制到文件:Files.copy(Path source, Path target, CopyOption options);
從輸入流復(fù)制到文件:Files.copy(InputStream in, Path target, CopyOption options);
從文件復(fù)制到輸出流: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)遍歷一個(gè)目錄和文件夾上面已經(jīng)介紹了: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)讀取和設(shè)置文件權(quán)限:
Path profile = Paths.get("/home/digdeep/.profile");
PosixFileAttributes attrs = Files.readAttributes(profile, PosixFileAttributes.class);// 讀取文件的權(quán)限
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); // 設(shè)置文件的權(quán)限
Files類(lèi)簡(jiǎn)直強(qiáng)大的一塌糊涂,幾乎所有文件和目錄的相關(guān)屬性,操作都有想要的api來(lái)支持。這里懶得再繼續(xù)介紹了,詳細(xì)參見(jiàn) jdk8 的文檔。
一個(gè)實(shí)際例子:
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();
}
}
}
場(chǎng)景是,sql server導(dǎo)出數(shù)據(jù)時(shí),會(huì)將 datatime 導(dǎo)成16進(jìn)制的binary格式,形如:, CAST(0x0000A2A500FC2E4F AS DateTime))
所以上面的程序是將最后一個(gè) datatime 字段導(dǎo)出的 , CAST(0x0000A2A500FC2E4F AS DateTime) 刪除掉,生成新的不含有datetime字段值的sql 腳本。用來(lái)導(dǎo)入到mysql中。
做到半途,其實(shí)有更好的方法,使用sql yog可以很靈活的將sql server中的表以及數(shù)據(jù)導(dǎo)入到mysql中。使用sql server自帶的導(dǎo)出數(shù)據(jù)的功能,反而不好處理。
以上這篇基于java Files類(lèi)和Paths類(lèi)的用法(詳解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot+redis+Interceptor+自定義annotation實(shí)現(xiàn)接口自動(dòng)冪等
本篇文章給大家介紹了使用springboot和攔截器、redis來(lái)優(yōu)雅的實(shí)現(xiàn)接口冪等,對(duì)于冪等在實(shí)際的開(kāi)發(fā)過(guò)程中是十分重要的,因?yàn)橐粋€(gè)接口可能會(huì)被無(wú)數(shù)的客戶端調(diào)用,如何保證其不影響后臺(tái)的業(yè)務(wù)處理,如何保證其只影響數(shù)據(jù)一次是非常重要的,感興趣的朋友跟隨小編一起看看吧2019-07-07
編寫(xiě)調(diào)用新浪微博API的Java程序來(lái)發(fā)送微博
這篇文章主要介紹了編寫(xiě)調(diào)用新浪微博API的Java程序來(lái)發(fā)送微博的方法,只是展示了一個(gè)基本的程序框架而非一個(gè)完整的圖形化軟件:)需要的朋友可以參考下2015-11-11
深入解析Java中的編碼轉(zhuǎn)換以及編碼和解碼操作
這篇文章主要介紹了Java中的編碼轉(zhuǎn)換以及編碼和解碼操作,文中詳細(xì)解讀了編碼解碼的相關(guān)IO操作以及內(nèi)存使用方面的知識(shí),需要的朋友可以參考下2016-02-02
手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)
這篇文章主要介紹了通過(guò)實(shí)例了解JavaStream流的方法學(xué)習(xí)和總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-08-08
類(lèi)似Object監(jiān)視器方法的Condition接口(詳解)
下面小編就為大家?guī)?lái)一篇類(lèi)似Object監(jiān)視器方法的Condition接口(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
SpringBoot整合Hibernate Validator實(shí)現(xiàn)參數(shù)驗(yàn)證功能
這篇文章主要介紹了SpringBoot整合Hibernate Validator實(shí)現(xiàn)參數(shù)驗(yàn)證功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
springboot CompletableFuture異步線程池詳解
這篇文章主要介紹了springboot CompletableFuture異步線程池的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04

