欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于java Files类和Paths类的用法(详解)

程序员文章站 2024-04-01 15:58:28
java7中文件io发生了很大的变化,专门引入了很多新的类: import java.nio.file.directorystream; import java...

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 files类和paths类的用法(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。