Skip to content

Commit

Permalink
Read files via buffer on Windows
Browse files Browse the repository at this point in the history
This works around unrecognized characters that were showing up with some
CRLFs.

Closes fiji/fiji#368
  • Loading branch information
hinerm committed Nov 22, 2024
1 parent f4d8937 commit 5f57315
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions src/windowsMain/kotlin/file.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,33 @@ actual class File actual constructor(private val rawPath: String) {

@OptIn(ExperimentalForeignApi::class)
actual fun lines(): List<String> {
val lines = mutableListOf<String>()
var lines = listOf<String>()
memScoped {
val fileHandle = openFile(path) ?: return lines
try {
val fileSize = fileSize(fileHandle) ?: return lines
val size = min(fileSize, Int.MAX_VALUE.toLong()).toInt()
if (size < fileSize) warn("Reading only $size bytes of large file $path")
val buffer = allocArray<ByteVar>(size)
val buffer = ByteArray(1024)
val bytesRead = alloc<DWORDVar>()
// TODO: Is bytesRead < fileSize possible? If so, do we need to loop here?
if (ReadFile(fileHandle, buffer, size.toUInt(), bytesRead.ptr, null) != 0) {
lines.addAll(buffer.toKString().split(Regex("(\\r\\n|\\n)")))
} else {
printlnErr("Error reading file: ${GetLastError()}")
}
val content = StringBuilder()
do {
buffer.usePinned { pinned ->
if (ReadFile(
fileHandle,
pinned.addressOf(0),
buffer.size.toUInt(),
bytesRead.ptr,
null
) != 0
) {
val readCount = bytesRead.value.toInt()
if (readCount > 0) {
content.append(buffer.decodeToString(0, readCount));
}
} else {
printlnErr("Error reading file: ${GetLastError()}")
}
}
} while (bytesRead.value > 0U)
lines = content.split(Regex("\\r\\n|\\n"))
} finally {
CloseHandle(fileHandle)
}
Expand Down

1 comment on commit 5f57315

@ctrueden
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! πŸ™Œ

Please sign in to comment.