Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispose streams created by File.create #2184

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions src/app/Fake.IO.FileSystem/File.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ module File =
let internal utf8WithoutBom = new UTF8Encoding(false)

// Detect the encoding, from https://stackoverflow.com/questions/3825390/effective-way-to-find-any-files-encoding
let getEncoding def filename =
let getEncoding def filename =
// Read the BOM
let bom = Array.zeroCreate 4
let read =
use file = new FileStream(filename, FileMode.Open, FileAccess.Read)
file.Read(bom, 0, 4)

match bom |> Array.toList with
| _ when read < 2 -> def
| 0xffuy :: 0xfeuy :: _ -> Encoding.Unicode //UTF-16LE
Expand All @@ -47,8 +47,8 @@ module File =
let getEncodingOrUtf8WithoutBom = getEncodingOrDefault utf8WithoutBom

/// Raises an exception if the file doesn't exist on disk.
let checkExists fileName =
if not <| exists fileName then
let checkExists fileName =
if not <| exists fileName then
FileNotFoundException(sprintf "File %s does not exist." fileName) |> raise

/// Checks if all given files exist.
Expand All @@ -58,41 +58,41 @@ module File =
/// ## Parameters
///
/// - 'fileName' - Name of file from which the version is retrieved. The path can be relative.
let getVersion (fileName : string) =
let getVersion (fileName : string) =
Path.getFullName fileName
|> System.Diagnostics.FileVersionInfo.GetVersionInfo
|> fun x -> x.FileVersion.ToString()

/// Creates a file if it does not exist.
let create fileName =
let create fileName =
let file = FileInfo.ofPath fileName
if not file.Exists then
file.Create() |> ignore
if not file.Exists then
file.Create().Dispose()

/// Deletes a file if it exists.
let delete fileName =
let delete fileName =
let file = FileInfo.ofPath fileName
if file.Exists then
if file.Exists then
file.Delete()

/// Deletes the given files.
let deleteAll files = Seq.iter delete files

/// Active Pattern for determining file extension.
let (|EndsWith|_|) (extension : string) (file : string) =
let (|EndsWith|_|) (extension : string) (file : string) =
if file.EndsWith extension then Some()
else None

/// Reads a file line by line
let readWithEncoding (encoding : Encoding) (file : string) =
let readWithEncoding (encoding : Encoding) (file : string) =
seq {
use stream = File.OpenRead(file)
use textReader = new StreamReader(stream, encoding)
while not textReader.EndOfStream do
yield textReader.ReadLine()
}
let read (file : string) = readWithEncoding (getEncodingOrUtf8WithoutBom file) file

/// Reads the first line of a file. This can be helpful to read a password from file.
let readLineWithEncoding (encoding:Encoding) (file : string) =
use stream = File.OpenRead file
Expand All @@ -110,12 +110,12 @@ module File =
lines |> Seq.iter writer.WriteLine

let write append fileName (lines : seq<string>) = writeWithEncoding (getEncodingOrUtf8WithoutBom fileName) append fileName lines

/// Writes a byte array to a file
let writeBytes file bytes = File.WriteAllBytes(file, bytes)

/// Writes a string to a file
let writeStringWithEncoding (encoding:Encoding) append fileName (text : string) =
let writeStringWithEncoding (encoding:Encoding) append fileName (text : string) =
let fi = FileInfo.ofPath fileName
use file = fi.Open(if append then FileMode.Append else FileMode.Create)
use writer = new StreamWriter(file, encoding)
Expand All @@ -124,9 +124,9 @@ module File =
let writeString append fileName (text : string) = writeStringWithEncoding (getEncodingOrUtf8WithoutBom fileName) append fileName text

/// Replaces the file with the given string
let replaceContent fileName text =
let replaceContent fileName text =
let fi = FileInfo.ofPath fileName
if fi.Exists then
if fi.Exists then
fi.IsReadOnly <- false
fi.Delete()
writeString false fileName text
Expand All @@ -145,7 +145,7 @@ module File =
let readAsBytes file = File.ReadAllBytes file

/// Replaces the text in the given file
let applyReplace replaceF fileName =
let applyReplace replaceF fileName =
fileName
|> readAsString
|> replaceF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Fake.DotNet.MSBuild.fs" />
<Compile Include="Fake.IO.File.fs" />
<Compile Include="TestHelpers.fs" />
<Compile Include="SimpleHelloWorldTests.fs" />
<Compile Include="Main.fs" />
Expand Down
19 changes: 19 additions & 0 deletions src/test/Fake.Core.IntegrationTests/Fake.IO.File.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Fake.IO.FileIntegrationTests

open Fake.IO
open System.IO
open Expecto

[<Tests>]
let tests =
testList "Fake.IO.FileIntegraionTests" [
testCase "Files created using File.create can be used immediately - #2183" <| fun _ ->
let testFile = Path.combine (Path.GetTempPath ()) (Path.GetRandomFileName ())

File.create testFile
File.replaceContent testFile "Test"

let actualContent = File.readAsString testFile

Expect.equal actualContent "Test" "Unexpected content in test file"
]