@@ -92,21 +92,31 @@ internal class FileSource(private val path: Path) : RawSource {
9292 private var buffer: dynamic = null
9393 private var closed = false
9494 private var offset = 0
95+ private val fd = open(path)
96+
97+ private fun open (path : Path ): dynamic {
98+ if (! (fs.existsSync(path.path) as Boolean )) {
99+ throw FileNotFoundException (" File does not exist: ${path.path} " )
100+ }
101+ val fd = try {
102+ fs.openSync(path.path, " r" )
103+ } catch (e: Throwable ) {
104+ throw IOException (" Failed to open a file ${path.path} ." , e)
105+ }
106+ if (fd < 0 ) throw IOException (" Failed to open a file ${path.path} ." )
107+ return fd
108+ }
95109
96- @OptIn(ExperimentalUnsignedTypes ::class )
97110 override fun readAtMostTo (sink : Buffer , byteCount : Long ): Long {
98111 check(! closed) { " Source is closed." }
99112 if (byteCount == 0L ) {
100113 return 0
101114 }
102115 if (buffer == = null ) {
103116 try {
104- buffer = fs.readFileSync(path.toString() , null )
117+ buffer = fs.readFileSync(fd , null )
105118 } catch (t: Throwable ) {
106- if (fs.existsSync(path.path) as Boolean ) {
107- throw IOException (" Failed to read data from $path " , t)
108- }
109- throw FileNotFoundException (" File does not exist: $path " )
119+ throw IOException (" Failed to read data from ${path.path} " , t)
110120 }
111121 }
112122 val len: Int = buffer.length as Int
@@ -122,12 +132,27 @@ internal class FileSource(private val path: Path) : RawSource {
122132 }
123133
124134 override fun close () {
125- closed = true
135+ if (! closed) {
136+ closed = true
137+ fs.closeSync(fd)
138+ }
126139 }
127140}
128141
129- internal class FileSink (private val path : Path , private var append : Boolean ) : RawSink {
142+ internal class FileSink (path : Path , append : Boolean ) : RawSink {
130143 private var closed = false
144+ private val fd = open(path, append)
145+
146+ private fun open (path : Path , append : Boolean ): dynamic {
147+ val flags = if (append) " a" else " w"
148+ val fd = try {
149+ fs.openSync(path.path, flags)
150+ } catch (e: Throwable ) {
151+ throw IOException (" Failed to open a file ${path.path} ." , e)
152+ }
153+ if (fd < 0 ) throw IOException (" Failed to open a file ${path.path} ." )
154+ return fd
155+ }
131156
132157 override fun write (source : Buffer , byteCount : Long ) {
133158 check(! closed) { " Sink is closed." }
@@ -142,12 +167,7 @@ internal class FileSink(private val path: Path, private var append: Boolean) : R
142167 val buf = buffer.Buffer .allocUnsafe(segmentBytes)
143168 buf.fill(head.data, head.pos, segmentBytes)
144169 try {
145- if (append) {
146- fs.appendFileSync(path.toString(), buf)
147- } else {
148- fs.writeFileSync(path.toString(), buf)
149- append = true
150- }
170+ fs.writeFileSync(fd, buf)
151171 } catch (e: Throwable ) {
152172 throw IOException (" Write failed" , e)
153173 }
@@ -160,6 +180,9 @@ internal class FileSink(private val path: Path, private var append: Boolean) : R
160180 override fun flush () = Unit
161181
162182 override fun close () {
163- closed = true
183+ if (! closed) {
184+ closed = true
185+ fs.closeSync(fd)
186+ }
164187 }
165188}
0 commit comments