Skip to content

Commit fca3c18

Browse files
committed
async versions of File.WriteAll*
File.AsyncWriteAllBytes File.AsyncWriteAllText File.AsyncWriteAllLines example of use in AsyncFileExtensions.fsx File.AppendAll* to follow
1 parent 10b9a52 commit fca3c18

4 files changed

Lines changed: 78 additions & 0 deletions

File tree

FSharpx.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpx.Core", "src\FSharpx
1616
EndProject
1717
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{EFB3F0C2-10B4-4EF5-8FA7-CC39880067A1}"
1818
ProjectSection(SolutionItems) = preProject
19+
samples\AsyncFileExtensions.fsx = samples\AsyncFileExtensions.fsx
1920
samples\AsyncSeqObservable.fsx = samples\AsyncSeqObservable.fsx
2021
samples\AutoCancel.fsx = samples\AutoCancel.fsx
2122
samples\BatchProcessing.fsx = samples\BatchProcessing.fsx

samples/AsyncFileExtensions.fsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
3+
//#r @"..\build\FSharpx.Core.dll"
4+
#r @"C:\Users\Ian\Documents\GitHub\Ian144\fsharpx\build\debug\FSharpx.Core.dll"
5+
6+
open Microsoft.FSharp.Control
7+
8+
9+
let lines = [| for n in 1..100000 do
10+
let str = sprintf "line: %d" n
11+
yield str |]
12+
13+
14+
15+
let asyncWriteA = System.IO.File.AsyncWriteAllLines(@"c:\tmp\a.txt", lines)
16+
let asyncWriteB = System.IO.File.AsyncWriteAllLines(@"c:\tmp\b.txt", lines)
17+
let asyncWriteC = System.IO.File.AsyncWriteAllLines(@"c:\tmp\c.txt", lines)
18+
let asyncWriteD = System.IO.File.AsyncWriteAllLines(@"c:\tmp\d.txt", lines)
19+
let asyncWriteE = System.IO.File.AsyncWriteAllText( @"c:\tmp\e.txt", "this is some text")
20+
21+
printfn "async write all lines begining"
22+
23+
[|asyncWriteA; asyncWriteB; asyncWriteC; asyncWriteD; asyncWriteE|]
24+
|> Async.Parallel
25+
|> Async.RunSynchronously
26+
|> ignore
27+
28+
29+
30+
printfn "async write all lines complete"

src/FSharpx.Core/AsyncOperations.fs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/FSharpx.Core/AsyncOperations.fsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ namespace Microsoft.FSharp.Control
6262
static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int -> Async<FileStream>
6363
#else
6464
static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int * ?options: FileOptions -> Async<FileStream>
65+
66+
// Aims to take advantage of IO completion ports using FileStream.AsyncWrite and FileOptions.Asynchronous, so no FX_NO_FILE_OPTIONS version
67+
static member AsyncWriteAllBytes: path:string * bytes:byte array -> Async<unit>
68+
69+
static member AsyncWriteAllText: path:string * txt:string * ?encoder:System.Text.Encoding -> Async<unit>
70+
static member AsyncWriteAllLines: path:string * lines:string array * ?encoder:System.Text.Encoding -> Async<unit>
6571
#endif
6672

6773
#if FX_NO_WEB_REQUESTS

0 commit comments

Comments
 (0)