forked from StarOpenSource/Engine
Fix FileAccess for good, add new 2 verify methods
This commit is contained in:
parent
32816ecce1
commit
c13eaead94
1 changed files with 126 additions and 31 deletions
|
@ -357,7 +357,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class)
|
||||
fun getType(): Type {
|
||||
return if (!exists()) Type.VOID
|
||||
return if (!exists(noFollowSymbolicLink = true)) Type.VOID
|
||||
else if (Files.isRegularFile(path)) Type.FILE
|
||||
else if (Files.isDirectory(path)) Type.DIRECTORY
|
||||
else Type.UNKNOWN
|
||||
|
@ -566,7 +566,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class)
|
||||
fun createFile(): FileAccess {
|
||||
if (!exists())
|
||||
if (!exists(noFollowSymbolicLink = true))
|
||||
try {
|
||||
logger.diag("Creating a file at '${unformatFromPath(path)}'")
|
||||
file.parentFile.mkdirs()
|
||||
|
@ -591,7 +591,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class)
|
||||
fun createDirectory(): FileAccess {
|
||||
if (!exists())
|
||||
if (!exists(noFollowSymbolicLink = true))
|
||||
try {
|
||||
logger.diag("Creating a directory at '${unformatFromPath(path)}'")
|
||||
file.mkdirs()
|
||||
|
@ -619,7 +619,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class)
|
||||
fun createLink(destination: FileAccess, hard: Boolean): FileAccess {
|
||||
if (!exists())
|
||||
if (!exists(noFollowSymbolicLink = true))
|
||||
try {
|
||||
logger.diag("Creating a ${if (hard) "hard" else "symbolic"} link at '${unformatFromPath(path)}'")
|
||||
if (hard) Files.createLink(path, destination.path)
|
||||
|
@ -707,7 +707,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class)
|
||||
fun delete(): FileAccess {
|
||||
if (exists())
|
||||
if (exists(noFollowSymbolicLink = true))
|
||||
try {
|
||||
logger.diag("Deleting '${unformatFromPath(path)}'")
|
||||
|
||||
|
@ -825,12 +825,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun writeBytes(bytes: ByteArray, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Writing to file '${path}' (bytes, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.write(path, bytes, StandardOpenOption.WRITE, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.write(path, bytes, StandardOpenOption.WRITE)
|
||||
else
|
||||
Files.write(path, bytes, StandardOpenOption.WRITE, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (bytes, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -855,12 +860,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun writeLines(lines: List<String>, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Writing to file '${path}' (lines, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.write(path, lines, StandardOpenOption.WRITE, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.write(path, lines, StandardOpenOption.WRITE)
|
||||
else
|
||||
Files.write(path, lines, StandardOpenOption.WRITE, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (lines, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -885,12 +895,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun writeString(string: String, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Writing to file '${path}' (string, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.writeString(path, string, StandardOpenOption.WRITE, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.writeString(path, string, StandardOpenOption.WRITE)
|
||||
else
|
||||
Files.writeString(path, string, StandardOpenOption.WRITE, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (string, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -915,12 +930,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun appendBytes(bytes: ByteArray, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Appending to file '${path}' (bytes, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.write(path, bytes, StandardOpenOption.APPEND, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.write(path, bytes, StandardOpenOption.APPEND)
|
||||
else
|
||||
Files.write(path, bytes, StandardOpenOption.APPEND, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (bytes, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -945,12 +965,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun appendLines(lines: List<String>, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Appending to file '${path}' (lines, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.write(path, lines, StandardOpenOption.APPEND, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.write(path, lines, StandardOpenOption.APPEND)
|
||||
else
|
||||
Files.write(path, lines, StandardOpenOption.APPEND, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (lines, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -975,12 +1000,17 @@ class FileAccess {
|
|||
@Throws(IOAccessException::class)
|
||||
fun appendString(string: String, async: Boolean = false): FileAccess {
|
||||
try {
|
||||
if (getType() != Type.FILE)
|
||||
return this
|
||||
when (getType()) {
|
||||
Type.UNKNOWN, Type.DIRECTORY -> return this
|
||||
else -> {}
|
||||
}
|
||||
|
||||
logger.diag("Appending to file '${path}' (string, ${if (async) "async" else ""})")
|
||||
createFile()
|
||||
Files.writeString(path, string, StandardOpenOption.APPEND, if (async) StandardOpenOption.DSYNC else StandardOpenOption.SYNC)
|
||||
if (async)
|
||||
Files.writeString(path, string, StandardOpenOption.APPEND)
|
||||
else
|
||||
Files.writeString(path, string, StandardOpenOption.APPEND, StandardOpenOption.SYNC)
|
||||
} catch (exception: Exception) {
|
||||
throw IOAccessException("Unable to read file '${path}' (string, ${if (async) "async" else ""})", exception)
|
||||
}
|
||||
|
@ -1105,14 +1135,21 @@ class FileAccess {
|
|||
* Verifies that something
|
||||
* exists at this location.
|
||||
*
|
||||
* This method does not follow symbolic links
|
||||
* and instead looks at the file directly. This
|
||||
* method should likely be used to check if
|
||||
* something exists at that exact location.
|
||||
* In case you may need to follow symbolic links,
|
||||
* use [verifyExistsLink] instead.
|
||||
*
|
||||
* @return this instance
|
||||
* @throws IOAccessException on IO error
|
||||
* @throws VerificationFailedException if the verification fails
|
||||
* @since v1-alpha10
|
||||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyExists(noFollowSymbolicLink: Boolean = false): FileAccess {
|
||||
if (!exists(noFollowSymbolicLink = noFollowSymbolicLink))
|
||||
fun verifyExists(): FileAccess {
|
||||
if (!exists(noFollowSymbolicLink = true))
|
||||
throw VerificationFailedException("Expected that something exists at '${unformatFromPath(path)}'")
|
||||
|
||||
return this
|
||||
|
@ -1122,19 +1159,76 @@ class FileAccess {
|
|||
* Verifies that something does
|
||||
* not exist at this location.
|
||||
*
|
||||
* This method does not follow symbolic links
|
||||
* and instead looks at the file directly. This
|
||||
* method should likely be used to check if
|
||||
* something exists at that exact location.
|
||||
* In case you may need to follow symbolic links,
|
||||
* use [verifyNotExistsLink] instead.
|
||||
*
|
||||
* @return this instance
|
||||
* @throws IOAccessException on IO error
|
||||
* @throws VerificationFailedException if the verification fails
|
||||
* @since v1-alpha10
|
||||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyNotExists(noFollowSymbolicLink: Boolean = false): FileAccess {
|
||||
if (exists(noFollowSymbolicLink = noFollowSymbolicLink))
|
||||
fun verifyNotExists(): FileAccess {
|
||||
if (exists(noFollowSymbolicLink = true))
|
||||
throw VerificationFailedException("Expected that nothing exists at '${unformatFromPath(path)}'")
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that something
|
||||
* exists at this location.
|
||||
*
|
||||
* This method follows symbolic links during
|
||||
* the verification process, which should
|
||||
* only be used to check if you can read/write
|
||||
* from a file. In case you need to verify the
|
||||
* existence of this very file and do not
|
||||
* require following symbolic links, use the
|
||||
* [verifyNotExists] method instead.
|
||||
*
|
||||
* @return this instance
|
||||
* @throws IOAccessException on IO error
|
||||
* @throws VerificationFailedException if the verification fails
|
||||
* @since v1-alpha10
|
||||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyExistsLink(): FileAccess {
|
||||
if (!exists(noFollowSymbolicLink = false))
|
||||
throw VerificationFailedException("Expected the link destination of '${unformatFromPath(path)}' is dead")
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that something does
|
||||
* not exist at this location.
|
||||
*
|
||||
* This method follows symbolic links during
|
||||
* the verification process, which should
|
||||
* only be used to check if you can read/write
|
||||
* from a file. In case you need to verify the
|
||||
* existence of this very file and do not
|
||||
* require following symbolic links, use the
|
||||
* [verifyExists] method instead.
|
||||
*
|
||||
* @return this instance
|
||||
* @throws IOAccessException on IO error
|
||||
* @throws VerificationFailedException if the verification fails
|
||||
* @since v1-alpha10
|
||||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyNotExistsLink(): FileAccess {
|
||||
if (exists(noFollowSymbolicLink = false))
|
||||
throw VerificationFailedException("Expected that the link destination of '${unformatFromPath(path)}' exists")
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a file
|
||||
* is at this location.
|
||||
|
@ -1214,7 +1308,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyIsLink(): FileAccess {
|
||||
if (exists() && isSymbolicLink())
|
||||
if (exists(noFollowSymbolicLink = true) && isSymbolicLink())
|
||||
throw VerificationFailedException("Expected that '${unformatFromPath(path)}' is a link")
|
||||
|
||||
return this
|
||||
|
@ -1231,7 +1325,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyIsNotLink(): FileAccess {
|
||||
if (exists() && !isSymbolicLink())
|
||||
if (exists(noFollowSymbolicLink = true) && !isSymbolicLink())
|
||||
throw VerificationFailedException("Expected that '${unformatFromPath(path)}' is not a link")
|
||||
|
||||
return this
|
||||
|
@ -1248,7 +1342,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyIsValidLink(): FileAccess {
|
||||
if (exists() && (isSymbolicLink() || getLinkDestination() != null))
|
||||
if (exists(noFollowSymbolicLink = true) && (isSymbolicLink() || getLinkDestination() != null))
|
||||
throw VerificationFailedException("Expected that '${unformatFromPath(path)}' is a link")
|
||||
|
||||
return this
|
||||
|
@ -1265,7 +1359,7 @@ class FileAccess {
|
|||
*/
|
||||
@Throws(IOAccessException::class, VerificationFailedException::class)
|
||||
fun verifyIsNotValidLink(): FileAccess {
|
||||
if (exists() && !(isSymbolicLink() || getLinkDestination() != null))
|
||||
if (exists(noFollowSymbolicLink = true) && !(isSymbolicLink() || getLinkDestination() != null))
|
||||
throw VerificationFailedException("Expected that '${unformatFromPath(path)}' is not a link")
|
||||
|
||||
return this
|
||||
|
@ -1387,6 +1481,7 @@ class FileAccess {
|
|||
}
|
||||
|
||||
override fun visitFile(path: Path, attributes: BasicFileAttributes): FileVisitResult {
|
||||
path.toFile().delete()
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue