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.
1.8.0_131
2.12.3
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.
--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
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
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
.
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