A file's status is 3-valued:

  1. The file is verified to exist;
  2. The file is verified to not exist;
  3. The file's status is unknown, when program has not sufficient right to the file.

So !Files.exists(path) != Files.notExists(path).

If both exists and notExists return false, the existence of the file cannot be verified.

To verify a program can access a file as needed, use isReadable(path), isWritable(path), isExecutable(path) methods.

 Path = …
boolean isRegularExecutableFile = File.isRegularFile(file) & Files.isReadable(file) & Files.isExecutable(file);

When symbolic paths exists, 2 paths maybe direct to same file, use isSameFile(p1,p2) to compare.

 Path p1 = ...;
Path p2 = ...;
if (Files.isSameFile(p1,p2)){
//Code when 2 paths locate the same file
}

Delete a file/dir: deleteIfExists(path)

 try{
Files.delete(path);
}catch(NoSuchFileException x){
System.err.format("%s: no such " + "file or dir%n", path);
}catch(DirectoryNotEmptyException x){
System.err.format("%s not empty%n",path);
}catch(IOException x){
//File permissions problems are caught here.
System.err.println(x);
}

Copy a file/dir: Copy files may fail when target file exists, unless the REPLACE_EXISTING option is spec. Directory can be copied, but not with files inside it. When copy a symbolic link, the target of the link is copied, not the link. And if need to copy the link, spec. either NOFOLLOW_LINKS or REPLACE_EXISTING option. This method takes a varargs argument. 3 options are supported:

  1. REPLACE_EXISTING: if dir not empty, copy fails with FileAlreadyExistsException
  2. COPY_ATTRIBUTES: attributes are OS-spec. however, last-modified-time is across platform supported
  3. NOFOLLOW_LINKS
 //import static methods from package
import static java.nio.file.StandardCopyOption.*;
...
Files.copy(src,dest,Options...);

in addition to file copy, copy method can also be used to copy between file & stream.  Usage: copy(InputStream, Path, Options...) & copy(Path, OutputStream).

See this method to support copy recursively.

Move a file/dir: move(path, path, option...) fails if target exists, unless REPLACE_EXISTING spec. Empty dir can be moved, on UNIX systems, moving a dir is equaling to renaming a dir, in that circumstances, non-empty dir can be moved, too. Options:

  1. REPLACE_EXISTING: if target is symbolic link, the target is replaced without affecting the link it points to
  2. ATOMIC_MOVE: move as an atomic file operation, if OS does not support atomic move, throw exception. This option guarantees that any other process watching the directory the file will be moved to should access and get a complete file.
 //import static methods from package
import static java.nio.file.StandardCopyOption.*;
...
File.move(src,dest,REPLACE_EXISTING);

Metadata: what is metadata? "Data about other data". In OS, data is contained in files/dirs, so the metadata tracks info about each of the objects: is it a regular file, a dir or a link? Size, cdate, lmdate, owner, accpermissions?

readAttributes(path, String, Option); readAttributes(path, Class<A>, Option);

 //using the BasicFileAttributes class to retrive file attributes
Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);
System.out.println(attr.creationTime() + attr.lastAccessTime() +
attr.lastModifiedTime() + attr.isDirectory() + attr.isOther() +
attr.isRegularFile() + attr.isSymbolicLink() + attr.size());

Set the FileTime:

 Path file = ...;
BasicFileAttributes attr =
Files.readAttributes(file, BasicFileAttributes.class);
long currentTime = System.currentTimeMillis();
FileTime ft = FileTime.fromMillis(currentTime);
Files.setLastModifiedTime(file, ft);

Create Dirs:

 //createDirectory(path, FileAttribute<?>)
Path dir = ...;
Files.createDirectory(dir);
//way to set permission
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
Files.createDirectory(file, attr);

List all root dirs of filesystem:

 Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
for (Path name:dirs){
System.err.println(name);
}

List contents in Dir:

Usage: newDirectoryStream(path), return an object that implements DirectoryStream interface, this interface implements Iterable, so iterate through the directory stream, behaves well even in large directories.

 Path dir = ...;
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
for(Path file:stream){
System.out.println(file.getFileName);
}
}catch(IOException | DirectoryIteratorException x){
//IOException can never be thrown by this iteration.
//In this snippet, it can only be thrown by newDirectoryStream.
System.out.println(x);
}
 //file filter
DirectoryStream<Path> stream = Files.newDirectoryStream(dir, *.{java,jar}); //using DirectoryStream.Filter<T>, rewrite accept(), anonyinter class
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>(){
Public boolean accept(Path file) throws IOException{
try{
return (Files.isDirectory(file);
}catch (IOException x){
//Failed to determine it's a directory
System.err.println(x);
return false;
}
}
}; DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter);

Path Class & File Class conversion:

 Path path = Paths.get("1.txt");
//Convert a Path obj to File obj
File file = path.toFile();
file.getCanonicalFilePath();
//Convert a File obj to Path obj
path = file.toPath();
path.getFileName();

About Links & Symbolics:

  1. Symbolics: createSymbolicLink(link, target, attr);
  2. Hard Link: createLink(link, target);
  3. Use Files.isSymbolicLink(file) static method to determine. boolean
  4. Use Files.readSymbolicLink(link) to find the target of link, return type Path, if not a symbolic link, throws a NotLinkException

Basic steps to implement a watch service:

  1. Create a WatchService "watcher" for file system
  2. For each directory need monitoring, register with watcher, spec. the type of events wanted, receive a WatchKey instance for each dir registered
  3. implement an infinite loop to wait for incoming events, if triggered, key is signaled & placed into the watcher's queue
  4. Retrieve the key from queue, obtain the file name wanted from key
  5. Retrieve each pending event for the key (there might be multiple events) & process
  6. reset key, resume waiting
  7. Close service if no long needed by exit the thread or when it's .closed()
 //use the newWatchService() method in FileSystem class
WatchService watcher = FileSystems.getDefault().newWatchService();
//Any obj implements Watchable interface can be registered, include Path class
//Path class implements 2 register methods, choose one, the other takes a
//WatchEvent.Modifier. Choose the types to be monitored, supported
//StandardWatchEventKinds:
//ENTRY_CREATE
//ENTRY_DELETE
//ENTRY_MODIFY
//OVERFLOW - indicate the event have been lost or discarded, do not have to indicate this identifier to receive it.
//register a path instance for all three types:
import static java.nio.file.StandardWatchEventKinds.*; Path dir = ...;
try{
WatchKey key = dir.register(watcher,
ENTRY_CREATE,
ENTRY_MODIFY,
ENTRY_DELETE);
}catch (IOException x){
System.err.println(x);
}

Usage of WatchService API:

  • watcher.poll()
  • watcher.poll(long,TimeUnit)
  • watcher.take()
  • key.pollEvents(): fetch a list of WatchEvents(StandardWatchEventKinds)
  • (WatchEvent<?> event.kind()): get exactly the kind type, can be compared
  • (WatchEvent<Path> event).context(): return the filename related to signal
  • key.reset(): exit loop if this method returns false, prepare the key to be signaled again
 for (;;) {

     // wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
} for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind(); // This key is registered only
// for ENTRY_CREATE events,
// but an OVERFLOW event can
// occur regardless if events
// are lost or discarded.
if (kind == OVERFLOW) {
continue;
} // The filename is the
// context of the event.
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path filename = ev.context(); // Verify that the new
// file is a text file.
try {
// Resolve the filename against the directory.
// If the filename is "test" and the directory is "foo",
// the resolved name is "foo/test".
Path child = dir.resolve(filename);
if (!Files.probeContentType(child).equals("text/plain")) {
System.err.format("New file '%s'" +
" is not a plain text file.%n", filename);
continue;
}
} catch (IOException x) {
System.err.println(x);
continue;
} // Email the file to the
// specified email alias.
System.out.format("Emailing file %s%n", filename);
//Details left to reader....
} // Reset the key -- this step is critical if you want to
// receive further watch events. If the key is no longer valid,
// the directory is inaccessible so exit the loop.
boolean valid = key.reset();
if (!valid) {
break;
}
}

How to suppress warning of known safe operations?

 //Create a method that do the operation and suppress certain type of warning
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> cast(WatchEvent<?> event){
return (WatchEvent<Path>)event;
}

Always ok to use this API WatchService, if filesystem support file change notif, API takes advantage of it, if do not support, API will poll the filesystem itself, waiting for changes.

The Files.probeContentType determined by the platform's default file type detector. In windows, the detector might determine a file content to be application/x-java based on the .class extension. That may go wrong. So if needed, custom a FileTypeDetector.

Default File System: use FileSystems.getDefault() to retrieve the default file system.

Path String Separator: To get the default file path separator of file system, use FileSystems.getDefault().getSeparator() or File.separator.

File Stores/Root Dirs: use FileSystems.getDefault().getFileStores(), FileSystems.getDefault().getRootDirectories(), Iterable<FileStore>|Iterable<Path>. return a file's root by: Files.getFileStore(path) | path.getRoot()

java.nio.file package:

  • Path class: manipulating a path
  • Files class: file modification, attr related
  • FileSystem: info about file system

Java NIO Related的更多相关文章

  1. Five ways to maximize Java NIO and NIO.2--reference

    Java NIO -- the New Input/Output API package-- was introduced with J2SE 1.4 in 2002. Java NIO's purp ...

  2. IO的详细解释:It's all about buffers: zero-copy, mmap and Java NIO

    There are use cases where data need to be read from source to a sink without modification. In code t ...

  3. Five ways to maximize Java NIO and NIO.2--转

    原文地址:http://www.javaworld.com/article/2078654/java-se/java-se-five-ways-to-maximize-java-nio-and-nio ...

  4. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  5. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  6. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

  7. Java NIO概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...

  8. JAVA NIO Socket通道

      DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...

  9. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

随机推荐

  1. C#获取数字证书

    string Thumbprint = "C2489D912F247C187AA14B1291A6fB612281225D"; X509Store store = new X509 ...

  2. (转载)app ico图标字体制作

    图标字体化浅谈   在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复 ...

  3. VS2010编译错误 LNK 2019 unresolved external symbol错误解决办法

    Link错误有很多种,主要是没有在连接中加入lib文件路径,或者lib配置正确,传参错误 一个solution里面多个project之间引用其他project函数会出现这个错误,由于包含了头文件而没处 ...

  4. Python多进程multiprocessing使用示例

    mutilprocess简介 像线程一样管理进程,这个是mutilprocess的核心,他与threading很是相像,对多核CPU的利用率会比threading好的多. import multipr ...

  5. linux双线ip设置(不需额外增加路由表)

    linux 双线ip设置(不需额外增加路由表,只需修改下面就ok了)修改   vi /etc/iproute2/rt_tables              (增加电信和网通两个路由表) 增加252  ...

  6. Echart图表相关配置项的设置

    饼状图提示框单位显示 在{c}后面即可添加任意单位内容. 一条记录含有多组数据的柱状图单位显示 标注单位的显示. 目前还未找到方法实现,当鼠标移动到标注上时设置显示单位. 标线单位的显示

  7. Webdriver的设计模式:Page Object(页面模型)

    设计思想:面向对象,将单个页面所有可能用到元素封装到一个page类中,并提供一些常用的方法,其属性就代表页面元素,普通方法代表对元素所做的操作 以博客园的登录页面为例: import org.open ...

  8. html5 --基础笔记2

    1.autocomplete 可以给表单本身(不是fieldset)设置属性来禁用整个表单的自动完成功能 <form id="" method="" au ...

  9. java并发编程框架 Executor ExecutorService invokeall

    首先介绍两个重要的接口,Executor和ExecutorService,定义如下: public interface Executor { void execute(Runnable command ...

  10. 安卓Activity组件

     Activity生命周期 熟悉javaEE的朋友们都了解servlet技术,我们想要实现一个自己的servlet,需要继承相应的基类,重写它的方法,这些方法会在合适的时间被servlet容器调用.其 ...