Handle files with NIO.2.

When dealing with files recently, I use better-files. better-files itself is a Scala wrapper around Java NIO, but by the way, I didn't know much about the API around file operations added in Java NIO.2, so I'll use it.

NIO.2 What is NIO.2 in the first place? by the way. An API introduced in Java SE 7 that enhances NIO introduced in Java 1.4. Specifically, the following.

--File system interface --Asynchronous I / O --Completion of socket channel function

It incorporates functions that could not be incorporated into NIO. After this, we will look at files, the file system interface, as mentioned at the beginning.

The execution environment looks like this. Write in Scala.

It is assumed that you have imported the following.

scala> import java.nio.file._
scala> import java.io.File
scala> import java.nio.file.attribute._

java.nio.file.Path An interface that indicates the location of files and directories. I think Path is the key to this file system interface. It was strange that File also represents a directory, so it's nice to be able to think of paths.

Instance generation

--Use java.nio.file.Paths

scala> val path1 = Paths.get("dir/file.txt")
path1: java.nio.file.Path = dir/file.txt

--Use java.nio.file.FileSystems

scala> val path2 = FileSystems.getDefault.getPath("dir", "file.txt")
path2: java.nio.file.Path = dir/file.txt

--Conversion from java.io.File

scala> val file = new File("dir/file.txt")
file: java.io.File = dir/file.txt

scala> val path3 = file.toPath
path3: java.nio.file.Path = dir/file.txt

Absolute path / relative path

The examples so far have been written with relative paths. If you want to generate with an absolute path, it looks like the following.

scala> val absolutePath1 = Paths.get("/tmp/dir/file.txt")
absolutePath1: java.nio.file.Path = /tmp/dir/file.txt

scala> val absolutePath2 = Paths.get("/", "tmp", "dir", "file.txt")
absolutePath2: java.nio.file.Path = /tmp/dir/file.txt

Conversion to java.io.File

scala> val path = Paths.get("dir/file.txt")
path: java.nio.file.Path = dir/file.txt

scala> val file = path.toFile
file: java.io.File = dir/file.txt

java.nio.file.FileSystem Interface to the file system. It seems that normal file systems, ZIP files, and Jar files can be handled transparently with this interface.

java.nio.file.FileSystems It's a factory that generates FileSystem. In the example of generating Path, the platform default file system is acquired by the getDefalut method.

scala> val file = path1.toFile
file: java.io.File = dir/file.txt

java.nio.file.Paths I used it earlier, but there is only a method to generate Path, so it's a factory of Path. It's just calling FileSystems.getDefault.getPath inside, so it's better to use this one.

java.nio.file.Files An interface that handles files and directories. Basically, it's like passing Path and doing something for the actual file of that Path or decremation. Similar to FileUtils in commons IO.

I'm sure you will try using copy / move / delete, which you use frequently.

copy

scala> val src = Paths.get("dir/src.txt")
src: java.nio.file.Path = dir/src.txt

scala> val dest = Paths.get("dir/dest.txt")
dest: java.nio.file.Path = dir/dest.txt

scala> val path = Files.copy(src, dest)
path: java.nio.file.Path = dir/dest.txt

As the return value, the dest passed as an argument is returned as it is. If the src file does not exist, NoSuchFileException will occur. If the dest file exists, FileAlreadyExistsException will occur.

The copy method receives an interface called CopyOption with the third argument. Now you can decide how you want to copy. For example, StandardCopyOption.REPLACE_EXISTING can be specified to replace the file if it exists. See below for details.

-Enumeration StandardCopyOption -Enumeration LinkOption

move

scala> val src = Paths.get("dir/src.txt")
src: java.nio.file.Path = dir/src.txt

scala> val path = Files.move(src, dest)
path: java.nio.file.Path = dir/dest.txt

It's almost the same as copy.

If the dest file exists, a FileAlreadyExistsException will occur.

delete

scala> val path = Paths.get("dir/file.txt")
path: java.nio.file.Path = dir/file.txt

scala> Files.delete(path)

In case of delete, there is no return value. If you delete Path, it will be a non-existent thing, so it will not return anything.

If the file to be deleted does not exist, a NoSuchFileException will occur.

I tried using files here, but of course directories can be handled.

The API to operate by passing Path to Files is good. There are other methods that can get readers, writers, channels, and streams from Files, which is easier to handle than Files.

File attributes

In the case of File, only the attributes common to the OS can be handled, but in NIO.2, the attributes for each OS can also be handled. Attributes include file owner, creation date, modification date, and permissions.

I will actually get it.

scala> val path = Paths.get("dir/file.txt")
path: java.nio.file.Path = dir/file.txt

scala> val attributes = Files.getFileAttributeView(path, classOf[PosixFileAttributeView]).readAttributes()
attributes: java.nio.file.attribute.PosixFileAttributes = sun.nio.fs.UnixFileAttributes@364beb26


scala> attributes.creationTime
res0: java.nio.file.attribute.FileTime = 2017-08-28T22:45:16Z

scala> attributes.owner
res1: java.nio.file.attribute.UserPrincipal = asmasa

Of course you can also set it.

scala> Files.setLastModifiedTime(path, FileTime.fromMillis(System.currentTimeMillis()))
res2: java.nio.file.Path = dir/file.txt

scala> val owner = FileSystems.getDefault.getUserPrincipalLookupService .lookupPrincipalByName("test")
owner: java.nio.file.attribute.UserPrincipal = test

scala> Files.setOwner(path, owner)
res3: java.nio.file.Path = dir/file.txt

You can do it like this.

scala> Files.setAttribute(path, "lastModifiedTime", FileTime.fromMillis(System.currentTimeMillis()))
res4: java.nio.file.Path = dir/file.txt

I took a look at the NIO.2 file interface, but it's easier to use than when it was File. It's nice to understand that you operate through Files.

Recommended Posts

Handle files with NIO.2.
[Java] Handle Excel files with Apache POI
Handle devise with Rails
Handle JSON with minimal-json
Handle dates with Javascript (moment.js)
Easily handle war files on Windows
Download large files with Apache JMeter
[Ruby] Handle instance variables with instance methods
Handle DatePicker with Ruby / gtk3 + glade3
Handle JSON effortlessly with Alamofire's respone Json
Drag and drop files with JavaFX
Handle CSV files uploaded to GCS
[Java] Reading and writing files with OpenCSV
Delete folders and files with File Manager
[Kotlin] Delete files with duplicate contents [Java]
How to handle sign-in errors with devise