Skip to content

Commit 19d2f16

Browse files
Path overloads fixes
1 parent a903676 commit 19d2f16

File tree

11 files changed

+166
-63
lines changed

11 files changed

+166
-63
lines changed

core/api/core.api

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6421,12 +6421,26 @@ public abstract interface class org/jetbrains/kotlinx/dataframe/io/SupportedForm
64216421
}
64226422

64236423
public final class org/jetbrains/kotlinx/dataframe/io/SupportedFormatSample$DataFile : org/jetbrains/kotlinx/dataframe/io/SupportedFormatSample {
6424-
public static final synthetic fun box-impl (Ljava/nio/file/Path;)Lorg/jetbrains/kotlinx/dataframe/io/SupportedFormatSample$DataFile;
6424+
public static final synthetic fun box-impl (Ljava/io/File;)Lorg/jetbrains/kotlinx/dataframe/io/SupportedFormatSample$DataFile;
6425+
public static fun constructor-impl (Ljava/io/File;)Ljava/io/File;
6426+
public fun equals (Ljava/lang/Object;)Z
6427+
public static fun equals-impl (Ljava/io/File;Ljava/lang/Object;)Z
6428+
public static final fun equals-impl0 (Ljava/io/File;Ljava/io/File;)Z
6429+
public final fun getSampleFile ()Ljava/io/File;
6430+
public fun hashCode ()I
6431+
public static fun hashCode-impl (Ljava/io/File;)I
6432+
public fun toString ()Ljava/lang/String;
6433+
public static fun toString-impl (Ljava/io/File;)Ljava/lang/String;
6434+
public final synthetic fun unbox-impl ()Ljava/io/File;
6435+
}
6436+
6437+
public final class org/jetbrains/kotlinx/dataframe/io/SupportedFormatSample$DataPath : org/jetbrains/kotlinx/dataframe/io/SupportedFormatSample {
6438+
public static final synthetic fun box-impl (Ljava/nio/file/Path;)Lorg/jetbrains/kotlinx/dataframe/io/SupportedFormatSample$DataPath;
64256439
public static fun constructor-impl (Ljava/nio/file/Path;)Ljava/nio/file/Path;
64266440
public fun equals (Ljava/lang/Object;)Z
64276441
public static fun equals-impl (Ljava/nio/file/Path;Ljava/lang/Object;)Z
64286442
public static final fun equals-impl0 (Ljava/nio/file/Path;Ljava/nio/file/Path;)Z
6429-
public final fun getSampleFilePath ()Ljava/nio/file/Path;
6443+
public final fun getSamplePath ()Ljava/nio/file/Path;
64306444
public fun hashCode ()I
64316445
public static fun hashCode-impl (Ljava/nio/file/Path;)I
64326446
public fun toString ()Ljava/lang/String;

core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/guess.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ public sealed interface SupportedFormat {
3737
public sealed interface SupportedFormatSample {
3838

3939
@JvmInline
40-
public value class DataFile(public val sampleFilePath: Path) : SupportedFormatSample
40+
public value class DataFile(public val sampleFile: File) : SupportedFormatSample
41+
42+
@JvmInline
43+
public value class DataPath(public val samplePath: Path) : SupportedFormatSample
4144

4245
@JvmInline
4346
public value class DataUrl(public val sampleUrl: URL) : SupportedFormatSample
@@ -144,7 +147,7 @@ internal fun guessFormatForExtension(
144147
internal fun guessFormat(
145148
path: Path,
146149
formats: List<SupportedFormat> = supportedFormats,
147-
sample: SupportedFormatSample.DataFile? = SupportedFormatSample.DataFile(path),
150+
sample: SupportedFormatSample.DataPath? = SupportedFormatSample.DataPath(path),
148151
): SupportedFormat? = guessFormatForExtension(path.extension.lowercase(), formats, sample = sample)
149152

150153
internal fun guessFormat(

dataframe-arrow/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/ArrowWriter.kt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import java.io.File
1212
import java.io.OutputStream
1313
import java.nio.channels.Channels
1414
import java.nio.channels.WritableByteChannel
15-
import java.nio.file.Files
1615
import java.nio.file.Path
1716
import java.nio.file.StandardOpenOption
17+
import kotlin.io.path.outputStream
1818

1919
public val ignoreMismatchMessage: (ConvertingMismatch) -> Unit = { message: ConvertingMismatch -> }
2020
public val writeMismatchMessage: (ConvertingMismatch) -> Unit = { message: ConvertingMismatch ->
@@ -98,16 +98,18 @@ public interface ArrowWriter : AutoCloseable {
9898
writeArrowIPC(file.toPath(), append)
9999
}
100100

101-
/** Path overload for Arrow IPC writing. */
101+
/**
102+
* Save data to [Arrow interprocess streaming format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-streaming-format),
103+
* write to a new or existing file on the given [path].
104+
* If file on the given [path] exists, it can be recreated or expanded.
105+
*/
102106
public fun writeArrowIPC(path: Path, append: Boolean = true) {
103107
val options = if (append) {
104108
arrayOf(StandardOpenOption.CREATE, StandardOpenOption.APPEND)
105109
} else {
106110
arrayOf(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
107111
}
108-
Files.newOutputStream(path, *options).use { os ->
109-
writeArrowIPC(os)
110-
}
112+
path.outputStream(*options).use { outputStream -> writeArrowIPC(outputStream) }
111113
}
112114

113115
/**
@@ -141,20 +143,23 @@ public interface ArrowWriter : AutoCloseable {
141143

142144
/**
143145
* Save data to [Arrow random access format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-random-access-files), write to new or existing [file].
144-
* If file exists, it would be recreated.
146+
* If [file] exists, it would be recreated.
145147
*/
146148
public fun writeArrowFeather(file: File) {
147149
writeArrowFeather(file.toPath())
148150
}
149151

150-
/** Path overload for Arrow Feather writing. */
152+
/**
153+
* Save data to [Arrow random access format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-random-access-files),
154+
* write to a new or existing file on the given [path].
155+
* If file on the given [path] exists, it would be recreated.
156+
*/
151157
public fun writeArrowFeather(path: Path) {
152-
Files.newOutputStream(
153-
path,
158+
path.outputStream(
154159
StandardOpenOption.CREATE,
155160
StandardOpenOption.TRUNCATE_EXISTING,
156-
).use { os ->
157-
writeArrowFeather(os)
161+
).use { outputStream ->
162+
writeArrowFeather(outputStream)
158163
}
159164
}
160165

dataframe-arrow/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/arrowReading.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ public class ArrowFeather : SupportedDataFrameFormat {
2323
override fun readDataFrame(stream: InputStream, header: List<String>): AnyFrame =
2424
DataFrame.readArrowFeather(stream, NullabilityOptions.Widening)
2525

26-
override fun readDataFrame(file: File, header: List<String>): AnyFrame =
27-
DataFrame.readArrowFeather(file, NullabilityOptions.Widening)
28-
2926
override fun readDataFrame(path: Path, header: List<String>): AnyFrame =
3027
DataFrame.readArrowFeather(path, NullabilityOptions.Widening)
3128

@@ -80,7 +77,10 @@ public fun DataFrame.Companion.readArrowIPC(
8077
nullability: NullabilityOptions = NullabilityOptions.Infer,
8178
): AnyFrame = readArrowIPC(file.toPath(), nullability)
8279

83-
/** Path overload for reading Arrow IPC from file path. */
80+
/**
81+
* Read [Arrow interprocess streaming format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-streaming-format)
82+
* data from existing file on the given [path].
83+
*/
8484
public fun DataFrame.Companion.readArrowIPC(
8585
path: Path,
8686
nullability: NullabilityOptions = NullabilityOptions.Infer,
@@ -139,7 +139,10 @@ public fun DataFrame.Companion.readArrowFeather(
139139
nullability: NullabilityOptions = NullabilityOptions.Infer,
140140
): AnyFrame = readArrowFeather(file.toPath(), nullability)
141141

142-
/** Path overload for reading Arrow Feather from file path. */
142+
/**
143+
* Read [Arrow random access format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-random-access-files)
144+
* data from an existing file on the given [path].
145+
*/
143146
public fun DataFrame.Companion.readArrowFeather(
144147
path: Path,
145148
nullability: NullabilityOptions = NullabilityOptions.Infer,

dataframe-arrow/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/arrowWriting.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@ public fun AnyFrame.writeArrowIPC(stream: OutputStream) {
4444

4545
/**
4646
* Save data to [Arrow interprocess streaming format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-streaming-format), write to new or existing [file].
47-
* If file exists, it can be recreated or expanded.
47+
* If [file] exists, it can be recreated or expanded.
4848
*/
4949
public fun AnyFrame.writeArrowIPC(file: File, append: Boolean = true) {
5050
writeArrowIPC(file.toPath(), append)
5151
}
5252

53-
/** Path overload for IPC writing. */
53+
/**
54+
* Save data to [Arrow interprocess streaming format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-streaming-format),
55+
* write to new or existing file on the given [path].
56+
* If file exists, it can be recreated or expanded.
57+
*/
5458
public fun AnyFrame.writeArrowIPC(path: Path, append: Boolean = true) {
5559
this.arrowWriter().use { writer ->
5660
writer.writeArrowIPC(path, append)
@@ -93,7 +97,11 @@ public fun AnyFrame.writeArrowFeather(file: File) {
9397
writeArrowFeather(file.toPath())
9498
}
9599

96-
/** Path overload for Feather writing. */
100+
/**
101+
* Save data to [Arrow random access format](https://arrow.apache.org/docs/java/ipc.html#writing-and-reading-random-access-files),
102+
* write to new or existing file on the given [path].
103+
* If file exists, it would be recreated.
104+
*/
97105
public fun AnyFrame.writeArrowFeather(path: Path) {
98106
this.arrowWriter().use { writer ->
99107
writer.writeArrowFeather(path)

dataframe-excel/api/dataframe-excel.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ public final class org/jetbrains/kotlinx/dataframe/io/XlsxKt {
6161
public static final fun readExcel-Q2e6U8A (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/io/InputStream;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZ)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6262
public static final fun readExcel-Q2e6U8A (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZ)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6363
public static final fun readExcel-Q2e6U8A (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/net/URL;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZ)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
64+
public static final fun readExcel-Q2e6U8A (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/nio/file/Path;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZ)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6465
public static synthetic fun readExcel-Q2e6U8A$default (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/io/File;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6566
public static synthetic fun readExcel-Q2e6U8A$default (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/io/InputStream;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6667
public static synthetic fun readExcel-Q2e6U8A$default (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6768
public static synthetic fun readExcel-Q2e6U8A$default (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/net/URL;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
69+
public static synthetic fun readExcel-Q2e6U8A$default (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/nio/file/Path;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;ZZILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6870
public static final synthetic fun readExcel-ssqQo1E (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/io/File;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
6971
public static final synthetic fun readExcel-ssqQo1E (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/io/InputStream;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;
7072
public static final synthetic fun readExcel-ssqQo1E (Lorg/jetbrains/kotlinx/dataframe/DataFrame$Companion;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Lorg/jetbrains/kotlinx/dataframe/io/NameRepairStrategy;Z)Lorg/jetbrains/kotlinx/dataframe/DataFrame;

dataframe-excel/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/xlsx.kt

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import java.net.URL
4141
import java.nio.file.Files
4242
import java.nio.file.Path
4343
import java.util.Calendar
44+
import kotlin.io.path.exists
45+
import kotlin.io.path.fileSize
4446
import kotlin.io.path.inputStream
4547
import kotlin.io.path.outputStream
4648
import java.time.LocalDate as JavaLocalDate
@@ -50,9 +52,7 @@ import java.util.Date as JavaDate
5052
public class Excel : SupportedDataFrameFormat {
5153
override fun readDataFrame(stream: InputStream, header: List<String>): AnyFrame = DataFrame.readExcel(stream)
5254

53-
override fun readDataFrame(file: File, header: List<String>): AnyFrame = DataFrame.readExcel(file)
54-
55-
override fun readDataFrame(path: Path, header: List<String>): AnyFrame = DataFrame.readExcel(path.toFile())
55+
override fun readDataFrame(path: Path, header: List<String>): AnyFrame = DataFrame.readExcel(path)
5656

5757
override fun acceptsExtension(ext: String): Boolean = ext == "xls" || ext == "xlsx"
5858

@@ -189,22 +189,63 @@ public fun DataFrame.Companion.readExcel(
189189
nameRepairStrategy: NameRepairStrategy = NameRepairStrategy.CHECK_UNIQUE,
190190
firstRowIsHeader: Boolean = true,
191191
parseEmptyAsNull: Boolean = true,
192+
): AnyFrame =
193+
readExcel(
194+
file.toPath(),
195+
sheetName,
196+
skipRows,
197+
columns,
198+
stringColumns,
199+
rowsCount,
200+
nameRepairStrategy,
201+
firstRowIsHeader,
202+
parseEmptyAsNull,
203+
)
204+
205+
/**
206+
* @param sheetName sheet to read. By default, the first sheet in the document
207+
* @param columns comma separated list of Excel column letters and column ranges (e.g. “A:E” or “A,C,E:F”)
208+
* @param stringColumns range of columns to read as String regardless of a cell type.
209+
* For example, by default numeric cell with value "3" will be parsed as Double with value being 3.0. With this option, it will be simply "3"
210+
* @param skipRows number of rows before header
211+
* @param rowsCount number of rows to read.
212+
* @param nameRepairStrategy handling of column names.
213+
* The default behavior is [NameRepairStrategy.CHECK_UNIQUE].
214+
* @param firstRowIsHeader when set to true, it will take the first row (after skipRows) as the header.
215+
* when set to false, it operates as [NameRepairStrategy.MAKE_UNIQUE],
216+
* ensuring unique column names will make the columns be named according to excel columns, like "A", "B", "C" etc.
217+
* for unstructured data.
218+
* @param parseEmptyAsNull when set to true, empty strings in cells are parsed as null (default true).
219+
* These cells are ignored when inferring the column’s type.
220+
*/
221+
public fun DataFrame.Companion.readExcel(
222+
path: Path,
223+
sheetName: String? = null,
224+
skipRows: Int = 0,
225+
columns: String? = null,
226+
stringColumns: StringColumns? = null,
227+
rowsCount: Int? = null,
228+
nameRepairStrategy: NameRepairStrategy = NameRepairStrategy.CHECK_UNIQUE,
229+
firstRowIsHeader: Boolean = true,
230+
parseEmptyAsNull: Boolean = true,
192231
): AnyFrame {
193-
setWorkbookTempDirectory()
194-
@Suppress("ktlint:standard:comment-wrapping")
195-
val wb = WorkbookFactory.create(file, /* password = */ null, /* readOnly = */ true)
196-
return wb.use {
197-
readExcel(
198-
it,
199-
sheetName,
200-
skipRows,
201-
columns,
202-
stringColumns?.toFormattingOptions(),
203-
rowsCount,
204-
nameRepairStrategy,
205-
firstRowIsHeader,
206-
parseEmptyAsNull,
207-
)
232+
path.inputStream().use { inputStream ->
233+
setWorkbookTempDirectory()
234+
@Suppress("ktlint:standard:comment-wrapping")
235+
val wb = WorkbookFactory.create(inputStream, /* password = */ null)
236+
return wb.use {
237+
readExcel(
238+
it,
239+
sheetName,
240+
skipRows,
241+
columns,
242+
stringColumns?.toFormattingOptions(),
243+
rowsCount,
244+
nameRepairStrategy,
245+
firstRowIsHeader,
246+
parseEmptyAsNull,
247+
)
248+
}
208249
}
209250
}
210251

@@ -642,7 +683,24 @@ public fun <T> DataFrame<T>.writeExcel(
642683
keepFile = keepFile,
643684
)
644685

645-
/** Path overload for writing this DataFrame to an Excel file. */
686+
/**
687+
* Writes this DataFrame to an Excel file as a single sheet.
688+
*
689+
* Implemented with [Apache POI](https://poi.apache.org) using `HSSFWorkbook` for XLS files,
690+
* `XSSFWorkbook` for standard XLSX files,
691+
* and `SXSSFWorkbook` for memory-efficient streaming when creating new XLSX files.
692+
*
693+
* @param path The path to a file where the data will be written.
694+
* @param columnsSelector A [selector][ColumnsSelector] to determine which columns to include in the file. The default is all columns.
695+
* @param sheetName The name of the sheet in the Excel file. If null, the default name will be used.
696+
* @param writeHeader A flag indicating whether to write the header row in the Excel file. Defaults to true.
697+
* @param workBookType The [type of workbook][WorkBookType] to create (e.g., XLS or XLSX). Defaults to XLSX.
698+
* @param keepFile If `true` and the file already exists, a new sheet will be appended instead of overwriting the file.
699+
* This may result in higher memory usage and slower performance compared to creating a new file.
700+
* Defaults to `false`.
701+
*
702+
* @throws [IllegalArgumentException] if the [sheetName] is invalid or workbook already contains a sheet with this name.
703+
*/
646704
public fun <T> DataFrame<T>.writeExcel(
647705
path: Path,
648706
columnsSelector: ColumnsSelector<T, *> = { all() },
@@ -652,7 +710,7 @@ public fun <T> DataFrame<T>.writeExcel(
652710
keepFile: Boolean = false,
653711
) {
654712
val factory =
655-
if (keepFile && Files.exists(path) && Files.size(path) > 0L) {
713+
if (keepFile && path.exists() && path.fileSize() > 0L) {
656714
val fis = path.inputStream()
657715
when (workBookType) {
658716
WorkBookType.XLS -> HSSFWorkbook(fis)

dataframe-geo/src/main/kotlin/org/jetbrains/kotlinx/dataframe/geo/io/write.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,29 @@ import org.geotools.geojson.feature.FeatureJSON
88
import org.jetbrains.kotlinx.dataframe.geo.GeoDataFrame
99
import org.jetbrains.kotlinx.dataframe.geo.geotools.toSimpleFeatureCollection
1010
import java.io.File
11-
import java.nio.file.Files
1211
import java.nio.file.Path
12+
import kotlin.io.path.createDirectories
13+
import kotlin.io.path.notExists
14+
import kotlin.io.path.outputStream
1315

1416
fun GeoDataFrame<*>.writeGeoJson(path: String): Unit = writeGeoJson(File(path))
1517

16-
/** Path overload for writing GeoJSON */
1718
fun GeoDataFrame<*>.writeGeoJson(path: Path) {
1819
val featureJSON = FeatureJSON()
19-
Files.newOutputStream(path).use { outputStream ->
20+
path.outputStream().use { outputStream ->
2021
featureJSON.writeFeatureCollection(toSimpleFeatureCollection(), outputStream)
2122
}
2223
}
2324

2425
fun GeoDataFrame<*>.writeGeoJson(file: File) {
25-
// TODO: adds ids that breaks order of reading
2626
writeGeoJson(file.toPath())
2727
}
2828

2929
fun GeoDataFrame<*>.writeShapefile(directoryPath: String): Unit = writeShapefile(File(directoryPath))
3030

31-
/** Path overload for writing Shapefile to a directory */
3231
fun GeoDataFrame<*>.writeShapefile(directory: Path) {
33-
if (!Files.exists(directory)) {
34-
Files.createDirectories(directory)
32+
if (directory.notExists()) {
33+
directory.createDirectories()
3534
}
3635
val fileName = directory.fileName.toString()
3736
val shp = directory.resolve("$fileName.shp")

0 commit comments

Comments
 (0)