@@ -133,6 +133,47 @@ namespace Microsoft.FSharp.Control
133133 System.IO.File.AsyncOpen( path, mode, ?access= access, ?share= share,? bufferSize= bufferSize,? options= options)
134134#endif
135135
136+ #if FX_ NO_ FILE_ OPTIONS
137+ #else
138+ // Aims to take advantage of IO completion ports using FileStream.AsyncWrite and FileOptions.Asynchronous, so no FX_NO_FILE_OPTIONS version
139+ static member AsyncWriteAllBytes ( path , bytes ) =
140+ let bufferSize = 4096 // as per File.WriteAllBytes
141+ async {
142+ use! fs = System.IO.File.AsyncOpen( path, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read, bufferSize, System.IO.FileOptions.Asynchronous)
143+ let! ret = fs.AsyncWrite bytes
144+ return ret
145+ }
146+
147+ static member AsyncWriteAllText ( path , ( txt : string ), ? encoder ) =
148+ let enc = match encoder with Some e -> e | None -> System.Text.Encoding.Default
149+ async {
150+ let bs = enc.GetBytes txt
151+ return ! System.IO.File.AsyncWriteAllBytes( path, bs)
152+ }
153+
154+ // Different memory profile to File.WriteAllLines, converts all lines to a byte[] before doing any writing, then a single write op.
155+ // Not good for writing huge files, but writing one line at a time, as per File.WriteAllLines has its own issues,
156+ // e.g. sequential application of async IO (so lines are written in order)
157+ static member AsyncWriteAllLines ( path , ( lines : string array ), ? encoder ) =
158+ let enc = match encoder with Some e -> e | None -> System.Text.Encoding.Default
159+ async {
160+ use memStrm = new System.IO.MemoryStream()
161+ use sWriter = new System.IO.StreamWriter( memStrm, enc)
162+ lines |> Array.iter ( fun line -> sWriter.WriteLine( line))
163+ do sWriter.Flush()
164+ let bs = memStrm.ToArray()
165+ return ! System.IO.File.AsyncWriteAllBytes( path, bs)
166+ }
167+
168+
169+ #endif
170+
171+
172+
173+
174+
175+
176+
136177 [<AutoOpen>]
137178 module StreamReaderExtensions =
138179 type System.IO.StreamReader with
0 commit comments