Introduce Path.createParentDirectories function #KT-53263
This commit is contained in:
committed by
Space Team
parent
cf10bb8871
commit
d2dc23d8bb
@@ -19,10 +19,10 @@ import java.nio.file.attribute.BasicFileAttributes
|
|||||||
* Note that if this function throws, partial copying may have taken place.
|
* Note that if this function throws, partial copying may have taken place.
|
||||||
*
|
*
|
||||||
* Unlike `File.copyRecursively`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
* Unlike `File.copyRecursively`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
||||||
* You can use the following approach to ensure that required intermediate directories are created:
|
* You can use the [createParentDirectories] function to ensure that required intermediate directories are created:
|
||||||
* ```
|
* ```
|
||||||
* sourcePath.copyToRecursively(
|
* sourcePath.copyToRecursively(
|
||||||
* destinationPath.apply { parent?.createDirectories() },
|
* destinationPath.createParentDirectories(),
|
||||||
* followLinks = false
|
* followLinks = false
|
||||||
* )
|
* )
|
||||||
* ```
|
* ```
|
||||||
@@ -93,10 +93,10 @@ public fun Path.copyToRecursively(
|
|||||||
* Note that if this function throws, partial copying may have taken place.
|
* Note that if this function throws, partial copying may have taken place.
|
||||||
*
|
*
|
||||||
* Unlike `File.copyRecursively`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
* Unlike `File.copyRecursively`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
||||||
* You can use the following approach to ensure that required intermediate directories are created:
|
* You can use the [createParentDirectories] function to ensure that required intermediate directories are created:
|
||||||
* ```
|
* ```
|
||||||
* sourcePath.copyToRecursively(
|
* sourcePath.copyToRecursively(
|
||||||
* destinationPath.apply { parent?.createDirectories() },
|
* destinationPath.createParentDirectories(),
|
||||||
* followLinks = false
|
* followLinks = false
|
||||||
* )
|
* )
|
||||||
* ```
|
* ```
|
||||||
|
|||||||
@@ -189,9 +189,9 @@ private object PathRelativizer {
|
|||||||
* Copies a file or directory located by this path to the given [target] path.
|
* Copies a file or directory located by this path to the given [target] path.
|
||||||
*
|
*
|
||||||
* Unlike `File.copyTo`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
* Unlike `File.copyTo`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
||||||
* You can use the following approach to ensure that required intermediate directories are created:
|
* You can use the [createParentDirectories] function to ensure that required intermediate directories are created:
|
||||||
* ```
|
* ```
|
||||||
* sourcePath.copyTo(destinationPath.apply { parent?.createDirectories() })
|
* sourcePath.copyTo(destinationPath.createParentDirectories())
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* If the [target] path already exists, this function will fail unless [overwrite] argument is set to `true`.
|
* If the [target] path already exists, this function will fail unless [overwrite] argument is set to `true`.
|
||||||
@@ -226,9 +226,9 @@ public inline fun Path.copyTo(target: Path, overwrite: Boolean = false): Path {
|
|||||||
* Copies a file or directory located by this path to the given [target] path.
|
* Copies a file or directory located by this path to the given [target] path.
|
||||||
*
|
*
|
||||||
* Unlike `File.copyTo`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
* Unlike `File.copyTo`, if some directories on the way to the [target] are missing, then they won't be created automatically.
|
||||||
* You can use the following approach to ensure that required intermediate directories are created:
|
* You can use the [createParentDirectories] function to ensure that required intermediate directories are created:
|
||||||
* ```
|
* ```
|
||||||
* sourcePath.copyTo(destinationPath.apply { parent?.createDirectories() })
|
* sourcePath.copyTo(destinationPath.createParentDirectories())
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* If the [target] path already exists, this function will fail unless the
|
* If the [target] path already exists, this function will fail unless the
|
||||||
@@ -500,6 +500,8 @@ public inline fun Path.deleteIfExists() =
|
|||||||
* when creating the directory.
|
* when creating the directory.
|
||||||
*
|
*
|
||||||
* @see Files.createDirectory
|
* @see Files.createDirectory
|
||||||
|
* @see Path.createDirectories
|
||||||
|
* @see Path.createParentDirectories
|
||||||
*/
|
*/
|
||||||
@SinceKotlin("1.5")
|
@SinceKotlin("1.5")
|
||||||
@WasExperimental(ExperimentalPathApi::class)
|
@WasExperimental(ExperimentalPathApi::class)
|
||||||
@@ -513,15 +515,20 @@ public inline fun Path.createDirectory(vararg attributes: FileAttribute<*>): Pat
|
|||||||
*
|
*
|
||||||
* If the directory already exists, this function does not throw an exception, unlike [Path.createDirectory].
|
* If the directory already exists, this function does not throw an exception, unlike [Path.createDirectory].
|
||||||
*
|
*
|
||||||
|
* @return the path of this directory if it already exists or has been created successfully.
|
||||||
|
* The returned path can be converted [Path.toAbsolutePath][to absolute path] if it was relative.
|
||||||
|
*
|
||||||
* @param attributes an optional list of file attributes to set atomically when creating the directory.
|
* @param attributes an optional list of file attributes to set atomically when creating the directory.
|
||||||
*
|
*
|
||||||
* @throws FileAlreadyExistsException if there is already a file located by this path
|
* @throws FileAlreadyExistsException if there is already a file located by this path or one of its parent paths
|
||||||
* (optional specific exception, some implementations may throw more general [IOException]).
|
* (optional specific exception, some implementations may throw more general [IOException]).
|
||||||
* @throws IOException if an I/O error occurs.
|
* @throws IOException if an I/O error occurs.
|
||||||
* @throws UnsupportedOperationException if the [attributes ]array contains an attribute that cannot be set atomically
|
* @throws UnsupportedOperationException if the [attributes] array contains an attribute that cannot be set atomically
|
||||||
* when creating the directory.
|
* when creating the directory.
|
||||||
*
|
*
|
||||||
* @see Files.createDirectories
|
* @see Files.createDirectories
|
||||||
|
* @see Path.createDirectory
|
||||||
|
* @see Path.createParentDirectories
|
||||||
*/
|
*/
|
||||||
@SinceKotlin("1.5")
|
@SinceKotlin("1.5")
|
||||||
@WasExperimental(ExperimentalPathApi::class)
|
@WasExperimental(ExperimentalPathApi::class)
|
||||||
@@ -530,6 +537,33 @@ public inline fun Path.createDirectory(vararg attributes: FileAttribute<*>): Pat
|
|||||||
public inline fun Path.createDirectories(vararg attributes: FileAttribute<*>): Path =
|
public inline fun Path.createDirectories(vararg attributes: FileAttribute<*>): Path =
|
||||||
Files.createDirectories(this, *attributes)
|
Files.createDirectories(this, *attributes)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that all parent directories of this path exist, creating them if required.
|
||||||
|
*
|
||||||
|
* If the parent directory already exists, this function does nothing.
|
||||||
|
*
|
||||||
|
* Note that the [parent][Path.getParent] directory is not always the directory that contains the entry specified by this path.
|
||||||
|
* For example, the parent of the path `x/y/.` is `x/y`, which is logically the same directory,
|
||||||
|
* and the parent of `x/y/..` (which means just `x/`) is also `x/y`.
|
||||||
|
* Use the function [Path.normalize] to eliminate redundant name elements from the path.
|
||||||
|
*
|
||||||
|
* @param attributes an optional list of file attributes to set atomically when creating the missing parent directories.
|
||||||
|
*
|
||||||
|
* @return this path unchanged if all parent directories already exist or have been created successfully.
|
||||||
|
*
|
||||||
|
* @throws FileAlreadyExistsException if there is already a file located by the [parent][Path.getParent] path or one of its parent paths
|
||||||
|
* (optional specific exception, some implementations may throw more general [IOException]).
|
||||||
|
* @throws IOException if an I/O error occurs.
|
||||||
|
* @throws UnsupportedOperationException if the [attributes] array contains an attribute that cannot be set atomically
|
||||||
|
* when creating the directory.
|
||||||
|
*
|
||||||
|
* @see Path.getParent
|
||||||
|
* @see Path.createDirectories
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.9")
|
||||||
|
@Throws(IOException::class)
|
||||||
|
public fun Path.createParentDirectories(vararg attributes: FileAttribute<*>): Path =
|
||||||
|
this.apply { parent?.createDirectories(*attributes) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves or renames the file located by this path to the [target] path.
|
* Moves or renames the file located by this path to the [target] path.
|
||||||
|
|||||||
@@ -59,6 +59,45 @@ class PathExtensionsTest : AbstractPathTest() {
|
|||||||
assertFailsWith<FileAlreadyExistsException> { file.createFile() }
|
assertFailsWith<FileAlreadyExistsException> { file.createFile() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createParentDirectories() {
|
||||||
|
val dir = createTempDirectory().cleanupRecursively()
|
||||||
|
val file = dir / "test-dir" / "sub-dir" / "new-file"
|
||||||
|
val parent = file.parent!!
|
||||||
|
|
||||||
|
assertTrue(file.notExists())
|
||||||
|
assertTrue(parent.notExists())
|
||||||
|
|
||||||
|
val result = file.createParentDirectories()
|
||||||
|
assertTrue(file.notExists())
|
||||||
|
assertTrue(parent.isDirectory())
|
||||||
|
assertEquals(file, result)
|
||||||
|
|
||||||
|
file.createFile()
|
||||||
|
file.createParentDirectories()
|
||||||
|
assertTrue(file.exists())
|
||||||
|
assertTrue(parent.isDirectory())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createParentDirectoriesRelativePath() {
|
||||||
|
run {
|
||||||
|
val path = Path("test_path_without_parent")
|
||||||
|
path.createParentDirectories()
|
||||||
|
assertTrue(path.toAbsolutePath().parent!!.isDirectory())
|
||||||
|
}
|
||||||
|
|
||||||
|
run {
|
||||||
|
val path = Path("build/test_subdirectory/test_path")
|
||||||
|
val parent = path.parent!!
|
||||||
|
assertTrue(parent.notExists())
|
||||||
|
parent.cleanupRecursively()
|
||||||
|
path.createParentDirectories()
|
||||||
|
assertTrue(path.notExists())
|
||||||
|
assertTrue(parent.isDirectory())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun createTempFileDefaultDir() {
|
fun createTempFileDefaultDir() {
|
||||||
val file1 = createTempFile().cleanup()
|
val file1 = createTempFile().cleanup()
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ class PathRecursiveFunctionsTest : AbstractPathTest() {
|
|||||||
OnErrorResult.SKIP_SUBTREE
|
OnErrorResult.SKIP_SUBTREE
|
||||||
})
|
})
|
||||||
|
|
||||||
src.copyToRecursively(dst.apply { parent?.createDirectories() }, followLinks = false)
|
src.copyToRecursively(dst.createParentDirectories(), followLinks = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+1
@@ -3361,6 +3361,7 @@ public final class kotlin/io/path/PathsKt {
|
|||||||
public static final fun copyToRecursively (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZZ)Ljava/nio/file/Path;
|
public static final fun copyToRecursively (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZZ)Ljava/nio/file/Path;
|
||||||
public static synthetic fun copyToRecursively$default (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZLkotlin/jvm/functions/Function3;ILjava/lang/Object;)Ljava/nio/file/Path;
|
public static synthetic fun copyToRecursively$default (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZLkotlin/jvm/functions/Function3;ILjava/lang/Object;)Ljava/nio/file/Path;
|
||||||
public static synthetic fun copyToRecursively$default (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZZILjava/lang/Object;)Ljava/nio/file/Path;
|
public static synthetic fun copyToRecursively$default (Ljava/nio/file/Path;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function3;ZZILjava/lang/Object;)Ljava/nio/file/Path;
|
||||||
|
public static final fun createParentDirectories (Ljava/nio/file/Path;[Ljava/nio/file/attribute/FileAttribute;)Ljava/nio/file/Path;
|
||||||
public static final fun createTempDirectory (Ljava/nio/file/Path;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;)Ljava/nio/file/Path;
|
public static final fun createTempDirectory (Ljava/nio/file/Path;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;)Ljava/nio/file/Path;
|
||||||
public static synthetic fun createTempDirectory$default (Ljava/nio/file/Path;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;ILjava/lang/Object;)Ljava/nio/file/Path;
|
public static synthetic fun createTempDirectory$default (Ljava/nio/file/Path;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;ILjava/lang/Object;)Ljava/nio/file/Path;
|
||||||
public static final fun createTempFile (Ljava/nio/file/Path;Ljava/lang/String;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;)Ljava/nio/file/Path;
|
public static final fun createTempFile (Ljava/nio/file/Path;Ljava/lang/String;Ljava/lang/String;[Ljava/nio/file/attribute/FileAttribute;)Ljava/nio/file/Path;
|
||||||
|
|||||||
Reference in New Issue
Block a user