Skip to content

Commit 9b88f89

Browse files
authored
Merge pull request #7 from Archinamon/imply_createTempFile
Imply additional helpful functions
2 parents 9d9af8a + 7a91d75 commit 9b88f89

File tree

14 files changed

+192
-10
lines changed

14 files changed

+192
-10
lines changed

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
plugins {
2-
kotlin("multiplatform") version "1.5.10"
2+
kotlin("multiplatform") version "1.7.10"
33
id("org.jetbrains.dokka") version "1.4.32"
44
id("maven-publish")
55
id("signing")
66
}
77

88
group = "me.archinamon"
9-
version = "1.3.5"
9+
version = "1.3.6"
1010

1111
val isRunningInIde: Boolean = System.getProperty("idea.active")
1212
?.toBoolean() == true

src/commonMain/kotlin/File.common.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ expect class File(pathname: String) {
1414
fun isDirectory(): Boolean
1515

1616
fun getAbsolutePath(): String
17+
fun length(): Long
1718

1819
fun exists(): Boolean
1920
fun canRead(): Boolean
@@ -43,6 +44,8 @@ expect fun File.readText(): String
4344

4445
expect fun File.appendText(text: String)
4546

47+
expect fun File.appendBytes(bytes: ByteArray)
48+
4649
expect fun File.writeText(text: String)
4750

4851
fun File.deleteRecursively(): Boolean = walkBottomUp()

src/commonMain/kotlin/Files.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package me.archinamon.fileio
2+
3+
object Files {
4+
private const val tempDirectory = "/tmp"
5+
private const val tempFileType = ".tmp"
6+
7+
fun createTempFile(prefix: String, suffix: String? = null): File {
8+
return createTempFile(prefix, suffix, File(tempDirectory))
9+
}
10+
11+
fun createTempFile(prefix: String, suffix: String? = null, dir: File): File {
12+
if (platform() == Platform.Windows) {
13+
throw UnsupportedOperationException("Do not supported on mingw yet, create tmp files/dirs manually!")
14+
}
15+
16+
val parent = dir.getAbsolutePath()
17+
if (!dir.exists()) {
18+
dir.mkdirs()
19+
}
20+
21+
if (!dir.canWrite()) {
22+
throw IllegalFileAccess(parent, "Can't create file in the directory")
23+
}
24+
25+
if (prefix.length < 3) {
26+
throw IllegalArgumentException("prefix should be at least 3 chars long, now — ${prefix.length}")
27+
}
28+
29+
val end = suffix ?: tempFileType
30+
return File("$parent/$prefix$end").apply {
31+
createNewFile()
32+
}
33+
}
34+
}

src/commonMain/kotlin/platform.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package me.archinamon.fileio
2+
3+
enum class Platform {
4+
Linux, Macos, Windows, JVM, JS
5+
}
6+
7+
expect fun platform(): Platform

src/commonTest/kotlin/FileTests.kt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,71 @@ class FileTests {
131131
assertTrue(testDestFile.delete(), "failed to cleanup test file")
132132
assertTrue(testDestFolder.delete(), "failed to cleanup directory")
133133
}
134+
135+
@Test
136+
fun testCreateTempFileAndDelete() {
137+
if (platform() == Platform.Windows) {
138+
return
139+
}
140+
141+
val testFile = Files.createTempFile("test")
142+
143+
assertContains(
144+
testFile.getAbsolutePath(),
145+
"/tmp/test.tmp".replace('/', filePathSeparator),
146+
message = "different path: ${testFile.getAbsolutePath()}"
147+
)
148+
assertTrue(testFile.exists(), "file should exist")
149+
assertTrue(testFile.canRead(), "file should be readable")
150+
assertTrue(testFile.canWrite(), "file should be writable")
151+
assertTrue(testFile.isFile(), "file should be considered a file")
152+
assertFalse(testFile.isDirectory(), "file should not be considered a directory")
153+
assertTrue(testFile.delete(), "delete file failed")
154+
}
155+
156+
@Test
157+
fun testCreateTempFileWithinCustomDirAndDelete() {
158+
if (platform() == Platform.Windows) {
159+
return
160+
}
161+
162+
val testDir = File("/tmp/testdir").apply { mkdirs() }
163+
val testFile = Files.createTempFile(prefix = "test", suffix = "all.t", dir = testDir)
164+
165+
assertContains(
166+
testFile.getAbsolutePath(),
167+
"/tmp/testdir/testall.t".replace('/', filePathSeparator),
168+
message = "different path: ${testFile.getAbsolutePath()}"
169+
)
170+
assertTrue(testFile.exists(), "file should exist")
171+
assertTrue(testFile.canRead(), "file should be readable")
172+
assertTrue(testFile.canWrite(), "file should be writable")
173+
assertTrue(testFile.isFile(), "file should be considered a file")
174+
assertFalse(testFile.isDirectory(), "file should not be considered a directory")
175+
assertTrue(testFile.delete(), "delete file failed")
176+
177+
assertTrue(testDir.deleteRecursively(), "error while deleting all files in dir")
178+
}
179+
180+
@Test
181+
fun testFileLengthAndAppendings() {
182+
if (platform() == Platform.Windows) {
183+
return
184+
}
185+
186+
val testFile = Files.createTempFile("test")
187+
val data = "testData"
188+
testFile.writeText(data)
189+
190+
assertTrue(testFile.exists(), "file should exists")
191+
assertEquals(data, testFile.readText())
192+
193+
val appendedData = "\nNew Text!"
194+
testFile.appendBytes(appendedData.encodeToByteArray())
195+
196+
assertEquals(data + appendedData, testFile.readText())
197+
assertEquals((data + appendedData).length.toLong(), testFile.length())
198+
199+
assertTrue(testFile.delete(), "delete file failed")
200+
}
134201
}

src/jsMain/kotlin/File.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ actual class File constructor(jsfile: JsFile) {
5454
return innerFile.name
5555
}
5656

57+
actual fun length(): Long {
58+
return innerFile.size.toLong()
59+
}
60+
5761
actual fun exists(): Boolean {
5862
return !virtual
5963
}
@@ -97,6 +101,11 @@ actual fun File.appendText(text: String) {
97101
writeText(newData)
98102
}
99103

104+
actual fun File.appendBytes(bytes: ByteArray) {
105+
val newData = readBytes() + bytes
106+
writeBytes(newData)
107+
}
108+
100109
actual fun File.writeText(text: String) {
101110
innerFile = JsFile(text.encodeToByteArray().toTypedArray(), innerFile.name)
102111
}

src/jsMain/kotlin/platform.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package me.archinamon.fileio
2+
3+
actual fun platform(): Platform = Platform.JS

src/jvmMain/kotlin/File.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
@file:Suppress("PackageDirectoryMismatch")
22
package me.archinamon.fileio
33

4+
import java.io.File as jvmFile
45
import java.net.URLConnection
56
import java.nio.charset.Charset
7+
import kotlin.io.appendBytes as kAppendBytes
68
import kotlin.io.readBytes as kReadBytes
79
import kotlin.io.writeBytes as kWriteBytes
810

9-
actual typealias File = java.io.File
11+
actual typealias File = jvmFile
1012

1113
actual val filePathSeparator by lazy { File.separatorChar }
1214

@@ -19,6 +21,8 @@ actual fun File.readText() = readText(Charset.defaultCharset())
1921

2022
actual fun File.writeBytes(bytes: ByteArray) = kWriteBytes(bytes)
2123

24+
actual fun File.appendBytes(bytes: ByteArray) = kAppendBytes(bytes)
25+
2226
actual fun File.appendText(text: String) = appendText(text, Charset.defaultCharset())
2327

24-
actual fun File.writeText(text: String) = writeText(text, Charset.defaultCharset())
28+
actual fun File.writeText(text: String) = writeText(text, Charset.defaultCharset())

src/jvmMain/kotlin/platform.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package me.archinamon.fileio
2+
3+
actual fun platform(): Platform = Platform.JVM
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package me.archinamon.fileio
2+
3+
actual fun platform(): Platform = Platform.Linux

0 commit comments

Comments
 (0)