6
6
package dotty .tools .io
7
7
8
8
import scala .language .implicitConversions
9
-
10
9
import java .io .RandomAccessFile
11
- import java .net .{ URI , URL }
10
+ import java .nio .file .{FileAlreadyExistsException , Files }
11
+ import java .net .{URI , URL }
12
+
12
13
import scala .util .Random .alphanumeric
13
14
14
15
/** An abstraction for filesystem paths. The differences between
@@ -54,10 +55,10 @@ object Path {
54
55
55
56
def apply (path : String ): Path = apply(new JFile (path))
56
57
def apply (jfile : JFile ): Path = try {
57
- if (jfile.isFile) new File (jfile)
58
- else if (jfile.isDirectory) new Directory (jfile)
59
- else new Path (jfile)
60
- } catch { case ex : SecurityException => new Path (jfile) }
58
+ if (jfile.isFile) new File (jfile.toPath )
59
+ else if (jfile.isDirectory) new Directory (jfile.toPath )
60
+ else new Path (jfile.toPath )
61
+ } catch { case ex : SecurityException => new Path (jfile.toPath ) }
61
62
62
63
/** Avoiding any shell/path issues by only using alphanumerics. */
63
64
private [io] def randomPrefix = alphanumeric take 6 mkString " "
@@ -70,16 +71,16 @@ import Path._
70
71
*
71
72
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
72
73
*/
73
- class Path private [io] (val jfile : JFile ) {
74
+ class Path private [io] (val jpath : JPath ) {
74
75
val separator = java.io.File .separatorChar
75
76
val separatorStr = java.io.File .separator
76
77
77
78
// conversions
78
- def toFile : File = new File (jfile )
79
- def toDirectory : Directory = new Directory (jfile )
80
- def toAbsolute : Path = if (isAbsolute) this else Path (jfile.getAbsolutePath() )
79
+ def toFile : File = new File (jpath )
80
+ def toDirectory : Directory = new Directory (jpath )
81
+ def toAbsolute : Path = if (isAbsolute) this else new Path (jpath.toAbsolutePath )
81
82
def toCanonical : Path = Path (jfile.getCanonicalPath())
82
- def toURI : URI = jfile.toURI ()
83
+ def toURI : URI = jpath.toUri ()
83
84
def toURL : URL = toURI.toURL()
84
85
85
86
/** If this path is absolute, returns it: otherwise, returns an absolute
@@ -90,7 +91,7 @@ class Path private[io] (val jfile: JFile) {
90
91
/** Creates a new Path with the specified path appended. Assumes
91
92
* the type of the new component implies the type of the result.
92
93
*/
93
- def / (child : Path ): Path = if (isEmpty) child else new Path (new JFile (jfile, child.path))
94
+ def / (child : Path ): Path = if (isEmpty) child else new Path (jpath.resolve( child.path))
94
95
def / (child : Directory ): Directory = / (child : Path ).toDirectory
95
96
def / (child : File ): File = / (child : Path ).toFile
96
97
@@ -111,9 +112,11 @@ class Path private[io] (val jfile: JFile) {
111
112
*/
112
113
def walk : Iterator [Path ] = walkFilter(_ => true )
113
114
115
+ def jfile : JFile = jpath.toFile
116
+
114
117
// identity
115
- def name : String = jfile.getName()
116
- def path : String = jfile.getPath()
118
+ def name : String = jpath.getFileName().toString
119
+ def path : String = jpath.toString
117
120
def normalize : Path = Path (jfile.getAbsolutePath())
118
121
119
122
def resolve (other : Path ) = if (other.isAbsolute || isEmpty) other else / (other)
@@ -141,12 +144,12 @@ class Path private[io] (val jfile: JFile) {
141
144
// the only solution <-- a comment which could have used elaboration
142
145
if (segments.nonEmpty && segments.last == " .." )
143
146
(path / " .." ).toDirectory
144
- else jfile .getParent match {
147
+ else jpath .getParent match {
145
148
case null =>
146
149
if (isAbsolute) toDirectory // it should be a root. BTW, don't need to worry about relative pathed root
147
150
else Directory (" ." ) // a dir under pwd
148
151
case x =>
149
- Directory (x)
152
+ Directory (x.toFile )
150
153
}
151
154
}
152
155
def parents : List [Directory ] = {
@@ -173,62 +176,68 @@ class Path private[io] (val jfile: JFile) {
173
176
def addExtension (ext : String ): Path = Path (path + " ." + ext)
174
177
// changes the existing extension out for a new one, or adds it
175
178
// if the current path has none.
176
- def changeExtension (ext : String ): Path = (
179
+ def changeExtension (ext : String ): Path =
177
180
if (extension == " " ) addExtension(ext)
178
181
else Path (path.stripSuffix(extension) + ext)
179
- )
180
182
181
183
// conditionally execute
182
184
def ifFile [T ](f : File => T ): Option [T ] = if (isFile) Some (f(toFile)) else None
183
185
def ifDirectory [T ](f : Directory => T ): Option [T ] = if (isDirectory) Some (f(toDirectory)) else None
184
186
185
187
// Boolean tests
186
- def canRead = jfile.canRead( )
187
- def canWrite = jfile.canWrite( )
188
- def exists = try jfile .exists() catch { case ex : SecurityException => false }
189
- def isFile = try jfile.isFile() catch { case ex : SecurityException => false }
188
+ def canRead = Files .isReadable(jpath )
189
+ def canWrite = Files .isWritable(jpath )
190
+ def exists = try Files .exists(jpath) catch { case ex : SecurityException => false }
191
+ def isFile = try Files .isRegularFile(jpath) catch { case ex : SecurityException => false }
190
192
def isDirectory =
191
- try jfile .isDirectory()
192
- catch { case ex : SecurityException => jfile.getPath == " ." }
193
- def isAbsolute = jfile .isAbsolute()
193
+ try Files .isDirectory(jpath )
194
+ catch { case ex : SecurityException => jpath.toString == " ." }
195
+ def isAbsolute = jpath .isAbsolute()
194
196
def isEmpty = path.length == 0
195
197
196
198
// Information
197
- def lastModified = jfile.lastModified( )
198
- def length = jfile.length( )
199
+ def lastModified = Files .getLastModifiedTime(jpath )
200
+ def length = Files .size(jpath )
199
201
200
202
// Boolean path comparisons
201
203
def endsWith (other : Path ) = segments endsWith other.segments
202
204
def isSame (other : Path ) = toCanonical == other.toCanonical
203
- def isFresher (other : Path ) = lastModified > other.lastModified
205
+ def isFresher (other : Path ) = lastModified.compareTo( other.lastModified) > 0
204
206
205
207
// creations
206
208
def createDirectory (force : Boolean = true , failIfExists : Boolean = false ): Directory = {
207
- val res = if (force) jfile.mkdirs() else jfile.mkdir()
209
+ val res = try {
210
+ if (force) Files .createDirectories(jpath) else Files .createDirectory(jpath)
211
+ true
212
+ } catch {
213
+ case _ : FileAlreadyExistsException => false
214
+ }
208
215
if (! res && failIfExists && exists) fail(" Directory '%s' already exists." format name)
209
216
else if (isDirectory) toDirectory
210
- else new Directory (jfile )
217
+ else new Directory (jpath )
211
218
}
212
219
def createFile (failIfExists : Boolean = false ): File = {
213
- val res = jfile.createNewFile()
220
+ val res = try { Files .createFile(jpath); true } catch { case e : FileAlreadyExistsException => false }
214
221
if (! res && failIfExists && exists) fail(" File '%s' already exists." format name)
215
222
else if (isFile) toFile
216
- else new File (jfile )
223
+ else new File (jpath )
217
224
}
218
225
219
226
// deletions
220
- def delete () = jfile .delete()
227
+ def delete (): Unit = Files .delete(jpath )
221
228
222
229
/** Deletes the path recursively. Returns false on failure.
223
230
* Use with caution!
224
231
*/
225
- def deleteRecursively (): Boolean = deleteRecursively(jfile)
226
- private def deleteRecursively (f : JFile ): Boolean = {
227
- if (f.isDirectory) f.listFiles match {
228
- case null =>
229
- case xs => xs foreach deleteRecursively
230
- }
231
- f.delete()
232
+ def deleteRecursively (): Boolean = deleteRecursively(jpath)
233
+ private def deleteRecursively (p : JPath ): Boolean = {
234
+ import scala .collection .JavaConverters ._
235
+ if (Files .isDirectory(p))
236
+ Files .list(p).iterator().asScala.foreach(deleteRecursively)
237
+ try {
238
+ Files .delete(p)
239
+ true
240
+ } catch { case _ : Throwable => false }
232
241
}
233
242
234
243
def truncate () =
0 commit comments