@@ -165,6 +165,37 @@ namespace Microsoft.FSharp.Control
165165 return ! System.IO.File.AsyncWriteAllBytes( path, bs)
166166 }
167167
168+ // Aims to take advantage of IO completion ports using FileStream.AsyncWrite and FileOptions.Asynchronous, so no FX_NO_FILE_OPTIONS version
169+ static member AsyncAppendAllBytes ( path , bytes ) =
170+ let bufferSize = 4096 // as per File.WriteAllBytes
171+ async {
172+ use! fs = System.IO.File.AsyncOpen( path, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.Read, bufferSize, System.IO.FileOptions.Asynchronous)
173+ let! ret = fs.AsyncWrite bytes
174+ return ret
175+ }
176+
177+ static member AsyncAppendAllText ( path , ( txt : string ), ? encoder ) =
178+ let enc = match encoder with Some e -> e | None -> System.Text.Encoding.Default
179+ async {
180+ let bs = enc.GetBytes txt
181+ return ! System.IO.File.AsyncAppendAllBytes( path, bs)
182+ }
183+
184+ // Different memory profile to File.WriteAllLines, converts all lines to a byte[] before doing any writing, then a single write op.
185+ // Not good for writing huge files, but writing one line at a time, as per File.WriteAllLines has its own issues,
186+ // e.g. sequential application of async IO (so lines are written in order)
187+ static member AsyncAppendAllLines ( path , ( lines : string array ), ? encoder ) =
188+ let enc = match encoder with Some e -> e | None -> System.Text.Encoding.Default
189+ async {
190+ use memStrm = new System.IO.MemoryStream()
191+ use sWriter = new System.IO.StreamWriter( memStrm, enc)
192+ lines |> Array.iter ( fun line -> sWriter.WriteLine( line))
193+ do sWriter.Flush()
194+ let bs = memStrm.ToArray()
195+ return ! System.IO.File.AsyncAppendAllBytes( path, bs)
196+ }
197+
198+
168199
169200#endif
170201
0 commit comments