diff --git a/libraries/stdlib/src/kotlin/io/ReadWrite.kt b/libraries/stdlib/src/kotlin/io/ReadWrite.kt index b2bb58d93a1..94a56ccaf7b 100644 --- a/libraries/stdlib/src/kotlin/io/ReadWrite.kt +++ b/libraries/stdlib/src/kotlin/io/ReadWrite.kt @@ -99,13 +99,13 @@ public fun Reader.readText(): String { } /** - * Copies this reader to the given [out] writer, returning the number of bytes copied. + * Copies this reader to the given [out] writer, returning the number of characters copied. * * **Note** it is the caller's responsibility to close both of these resources. * * @param out writer to write to. * @param bufferSize size of character buffer to use in process. - * @return number of bytes copies. + * @return number of characters copied. */ public fun Reader.copyTo(out: Writer, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long { var charsCopied: Long = 0 diff --git a/libraries/stdlib/src/kotlin/io/files/Utils.kt b/libraries/stdlib/src/kotlin/io/files/Utils.kt index 43ab4b65292..4a9cb93fa44 100644 --- a/libraries/stdlib/src/kotlin/io/files/Utils.kt +++ b/libraries/stdlib/src/kotlin/io/files/Utils.kt @@ -159,7 +159,7 @@ private fun File.toRelativeStringOrNull(base: File): String? { /** - * Copies this file to the given output [target], returning the number of bytes copied. + * Copies this file to the given [target] file. * * If some directories on a way to the [target] are missing, then they will be created. * If the [target] file already exists, this function will fail unless [overwrite] argument is set to `true`. @@ -171,12 +171,12 @@ private fun File.toRelativeStringOrNull(base: File): String? { * * @param overwrite `true` if destination overwrite is allowed. * @param bufferSize the buffer size to use when copying. - * @return the number of bytes copied or zero if the copied file was a directory. + * @return the [target] file. * @throws NoSuchFileException if the source file doesn't exist. * @throws FileAlreadyExistsException if the destination file already exists and 'rewrite' argument is set to `false`. * @throws IOException if any errors occur while copying. */ -public fun File.copyTo(target: File, overwrite: Boolean = false, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long { +public fun File.copyTo(target: File, overwrite: Boolean = false, bufferSize: Int = DEFAULT_BUFFER_SIZE): File { if (!this.exists()) { throw NoSuchFileException(file = this, reason = "The source file doesn't exist") } @@ -194,16 +194,17 @@ public fun File.copyTo(target: File, overwrite: Boolean = false, bufferSize: Int if (this.isDirectory) { if (!target.mkdirs()) throw FileSystemException(file = this, other = target, reason = "Failed to create target directory") - return 0 - } + } else { + target.parentFile?.mkdirs() - target.parentFile?.mkdirs() - - return this.inputStream().use { input -> - target.outputStream().use { output -> - input.copyTo(output, bufferSize) + this.inputStream().use { input -> + target.outputStream().use { output -> + input.copyTo(output, bufferSize) + } } } + + return target } /** @@ -280,7 +281,7 @@ public fun File.copyRecursively(target: File, if (src.isDirectory) { dstFile.mkdirs() } else { - if (src.copyTo(dstFile, overwrite) != src.length()) { + if (src.copyTo(dstFile, overwrite).length() != src.length()) { if (onError(src, IOException("src.length() != dst.length()")) == OnErrorAction.TERMINATE) return false } diff --git a/libraries/stdlib/test/io/Files.kt b/libraries/stdlib/test/io/Files.kt index e23e1dfb54c..db75007c52d 100644 --- a/libraries/stdlib/test/io/Files.kt +++ b/libraries/stdlib/test/io/Files.kt @@ -1,6 +1,7 @@ package test.io import java.io.* +import java.util.* import org.junit.Test as test import kotlin.io.walkTopDown import kotlin.test.* @@ -362,14 +363,13 @@ class FilesTest { srcFile.copyTo(dstFile) } - var len = srcFile.copyTo(dstFile, overwrite = true) - assertEquals(13L, len) - assertEquals(srcFile.readText(), dstFile.readText(Charsets.UTF_8), "copy with overwrite over existing file") + var dst = srcFile.copyTo(dstFile, overwrite = true) + assertTrue(dst === dstFile) + compareFiles(srcFile, dst, "copy with overwrite over existing file") assertTrue(dstFile.delete()) - len = srcFile.copyTo(dstFile) - assertEquals(13L, len) - assertEquals(srcFile.readText(Charsets.UTF_8), dstFile.readText(), "copy to new file") + dst = srcFile.copyTo(dstFile) + compareFiles(srcFile, dst, "copy to new file") assertTrue(dstFile.delete()) dstFile.mkdir() @@ -476,14 +476,18 @@ class FilesTest { } } + fun compareFiles(src: File, dst: File, message: String? = null) { + assertTrue(dst.exists()) + assertEquals(src.isFile, dst.isFile, message) + if (dst.isFile) { + assertTrue(Arrays.equals(src.readBytes(), dst.readBytes()), message) + } + } + fun compareDirectories(src: File, dst: File) { - for (file in src.walkTopDown()) { - val dstFile = dst.resolve(file.relativeTo(src)) - assertTrue(dstFile.exists()) - assertEquals(file.isFile, dstFile.isFile) - if (dstFile.isFile) { - assertEquals(file.readText(), dstFile.readText()) - } + for (srcFile in src.walkTopDown()) { + val dstFile = dst.resolve(srcFile.relativeTo(src)) + compareFiles(srcFile, dstFile) } }