diff --git a/src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs b/src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs
index f01ec0a..56b5f4a 100644
--- a/src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs
+++ b/src/System.IO.Abstractions.Extensions/IFileInfoExtensions.cs
@@ -1,5 +1,4 @@
-using System.Collections;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Text;
namespace System.IO.Abstractions
@@ -7,35 +6,125 @@ namespace System.IO.Abstractions
public static class IFileInfoExtensions
{
///
- /// Throws an exception if the file doesn't exists
+ /// Throws an exception if the doesn't exists
///
- /// File that will be checked for existance
+ /// File that will be checked for existance
/// Exception thrown if the file is not found
- public static void ThrowIfNotFound(this IFileInfo info)
+ public static void ThrowIfNotFound(this IFileInfo file)
{
- if (!info.Exists)
- throw new FileNotFoundException(StringResources.Format("COULD_NOT_FIND_FILE_EXCEPTION", info.FullName));
+ if (!file.Exists)
+ throw new FileNotFoundException(StringResources.Format("COULD_NOT_FIND_FILE_EXCEPTION", file.FullName));
}
///
- /// Creates an that can enumerate the lines of text in the file
+ /// Creates an that can enumerate the lines of text in the
///
- /// File to enumerate content
+ /// File to enumerate content
/// Returns an to enumerate the content of the file
- public static IEnumerable EnumerateLines(this IFileInfo info)
+ public static IEnumerable EnumerateLines(this IFileInfo file)
{
- return new LineEnumerable(info, null);
+ return new LineEnumerable(file, null);
}
///
- /// Creates an that can enumerate the lines of text in the file
+ /// Creates an that can enumerate the lines of text in the specified
/// using the specified
///
- /// File to enumerate content
+ /// File to enumerate content
/// Returns an to enumerate the content of the file
- public static IEnumerable EnumerateLines(this IFileInfo info, Encoding encoding)
+ public static IEnumerable EnumerateLines(this IFileInfo file, Encoding encoding)
{
- return new LineEnumerable(info, encoding);
+ return new LineEnumerable(file, encoding);
+ }
+
+ ///
+ /// Opens a for the in the specified
+ ///
+ /// File to open stream on
+ /// Mode to use when opening the file
+ /// A that can read or write data to the specified
+ public static FileSystemStream OpenFileStream(this IFileInfo file, FileMode mode)
+ {
+ return file.FileSystem.FileStream.New(file.FullName, mode);
+ }
+
+ ///
+ /// Creates a new empty .
+ /// If the file already exists, the file is truncated.
+ ///
+ /// File to create
+ /// The original so that methods calls can be chained
+ public static IFileInfo Truncate(this IFileInfo file)
+ {
+ using(var stream = file.OpenFileStream(FileMode.Create))
+ {
+ stream.Dispose();
+ }
+
+ return file;
+ }
+
+ ///
+ /// Writes the specified to the specified using the UTF-8 encoding.
+ /// If the file already exists and the flag is set to true, the file will be truncated.
+ ///
+ /// File to write to
+ /// Lines to write to file as text
+ /// Flag that specifies if the file can be overwritten if it exists
+ /// Exception thrown if the file already exists and the flag is set to
+ public static void WriteLines(this IFileInfo file, IEnumerable lines, bool overwrite = false)
+ {
+ using (var stream = file.OpenFileStream(GetWriteFileMode(file, overwrite)))
+ using (var writer = new StreamWriter(stream))
+ foreach(var line in lines)
+ {
+ writer.WriteLine(line);
+ }
+ }
+
+ ///
+ /// Writes the specified to the specified
+ /// using the specified .
+ /// If the file already exists and the flag is set to true, the file will be truncated.
+ ///
+ /// File to write to
+ /// Lines to write to file as text
+ /// Encoding to use when writing the to the text file
+ /// Flag that specifies if the file can be overwritten if it exists
+ /// Exception thrown if the file already exists and the flag is set to
+ public static void WriteLines(this IFileInfo file, IEnumerable lines, Encoding encoding, bool overwrite = false)
+ {
+ using (var stream = file.OpenFileStream(GetWriteFileMode(file, overwrite)))
+ using (var writer = new StreamWriter(stream, encoding))
+ foreach (var line in lines)
+ {
+ writer.WriteLine(line);
+ }
+ }
+
+ ///
+ /// Appends the specified to the specified
+ ///
+ /// File to append to
+ /// Lines to append to file as text
+ public static void AppendLines(this IFileInfo file, IEnumerable lines)
+ {
+ using (var writer = file.AppendText())
+ foreach (var line in lines)
+ {
+ writer.WriteLine(line);
+ }
+ }
+
+ private static FileMode GetWriteFileMode(IFileInfo info, bool overwrite)
+ {
+ if (!overwrite && info.Exists)
+ {
+ throw new IOException(StringResources.Format("CANNOT_OVERWRITE", info.FullName));
+ }
+
+ //if the file already exists it will be truncated
+ return FileMode.Create;
}
}
}
diff --git a/src/System.IO.Abstractions.Extensions/Resources.Designer.cs b/src/System.IO.Abstractions.Extensions/Resources.Designer.cs
index 941a55d..d24f193 100644
--- a/src/System.IO.Abstractions.Extensions/Resources.Designer.cs
+++ b/src/System.IO.Abstractions.Extensions/Resources.Designer.cs
@@ -60,6 +60,15 @@ internal Resources() {
}
}
+ ///
+ /// Looks up a localized string similar to The file '{0}' already exists..
+ ///
+ internal static string CANNOT_OVERWRITE {
+ get {
+ return ResourceManager.GetString("CANNOT_OVERWRITE", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Could not find file '{0}'..
///
@@ -79,7 +88,7 @@ internal static string COULD_NOT_FIND_PART_OF_PATH_EXCEPTION {
}
///
- /// Looks up a localized string similar to '{0}' is not an ancestor of '{1}'.
+ /// Looks up a localized string similar to '{0}' is not an ancestor of '{1}'..
///
internal static string NOT_AN_ANCESTOR {
get {
diff --git a/src/System.IO.Abstractions.Extensions/Resources.resx b/src/System.IO.Abstractions.Extensions/Resources.resx
index b031282..3293806 100644
--- a/src/System.IO.Abstractions.Extensions/Resources.resx
+++ b/src/System.IO.Abstractions.Extensions/Resources.resx
@@ -117,6 +117,9 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ The file '{0}' already exists.
+
Could not find file '{0}'.
@@ -124,6 +127,6 @@
Could not find a part of the path '{0}'.
- '{0}' is not an ancestor of '{1}'
+ '{0}' is not an ancestor of '{1}'.
\ No newline at end of file
diff --git a/tests/System.IO.Abstractions.Extensions.Tests/FileInfoExtensionsTests.cs b/tests/System.IO.Abstractions.Extensions.Tests/FileInfoExtensionsTests.cs
index 43ff25c..57aacf3 100644
--- a/tests/System.IO.Abstractions.Extensions.Tests/FileInfoExtensionsTests.cs
+++ b/tests/System.IO.Abstractions.Extensions.Tests/FileInfoExtensionsTests.cs
@@ -1,5 +1,4 @@
using NUnit.Framework;
-using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -34,10 +33,7 @@ public void ThrowIfNotFound_IfFileExists_DoesNotThrowException()
var file = current.File(guid);
//act
- using (var stream = file.Create())
- {
- stream.Dispose();
- }
+ file.Truncate();
file.ThrowIfNotFound();
//assert
@@ -47,6 +43,50 @@ public void ThrowIfNotFound_IfFileExists_DoesNotThrowException()
file.Delete();
}
+ [Test]
+ public void Truncate_AnExistingFileWithContent_FileExistsAndIsEmpty()
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+ //create file
+ using (var stream = file.OpenWrite())
+ using (var writer = new StreamWriter(stream, Encoding.UTF8))
+ {
+ writer.WriteLine("test");
+ }
+ file.Refresh();
+ Assert.IsTrue(file.Exists);
+ Assert.IsTrue(file.Length >= 4);
+
+ //act
+ file.Truncate();
+
+ //assert
+ file.Refresh();
+ Assert.AreEqual(0, file.Length);
+ }
+
+ [Test]
+ public void Truncate_ANewFile_FileExistsAndIsEmpty()
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+ Assert.IsFalse(file.Exists);
+
+ //act
+ file.Truncate();
+
+ //assert
+ file.Refresh();
+ Assert.AreEqual(0, file.Length);
+ }
+
[TestCase("line1", "line2", "line3")]
[TestCase("line1", "", "line3")]
public void EnumerateLines_ReadFromExistingFile_ReturnsLines(params string[] content)
@@ -60,7 +100,7 @@ public void EnumerateLines_ReadFromExistingFile_ReturnsLines(params string[] con
using (var stream = file.OpenWrite())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
- foreach(var line in content)
+ foreach (var line in content)
writer.WriteLine(line);
}
@@ -69,10 +109,186 @@ public void EnumerateLines_ReadFromExistingFile_ReturnsLines(params string[] con
//assert
Assert.AreEqual(content.Length, actual.Length);
- for(int i=0; i(() => file.WriteLines(content));
+ var ex2 = Assert.Throws(() => file.WriteLines(content, false));
+
+ Assert.IsTrue(ex1.Message.Contains(file.FullName));
+ Assert.IsTrue(ex2.Message.Contains(file.FullName));
+ }
+
+ [TestCase("line1", "line2", "line3")]
+ [TestCase("line1", "", "line3")]
+ public void WriteLines_WriteLinesToExistingFileWithOverwriteEnabled_FileIsTruncatedAndLinesAreWritten(params string[] content)
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+
+ //create file with long content
+ var data = Encoding.UTF8.GetBytes("line5 line4 line3 line2 line1");
+ using (var stream = file.OpenWrite())
+ {
+ stream.Write(data, 0, data.Length);
+ stream.Dispose();
+ }
+
+ //act
+ Assert.IsTrue(file.Exists);
+ file.WriteLines(content, overwrite: true);
+ var actual = file.EnumerateLines().ToArray();
+
+ //assert
+ Assert.AreEqual(content.Length, actual.Length);
+ for (int i = 0; i < content.Length; i++)
+ {
+ Assert.AreEqual(content[i], actual[i]);
+ }
+ }
+
+ [TestCase("line1", "line2", "line3")]
+ [TestCase("line1", "", "line3")]
+ public void WriteLinesWithUTF16Encoding_WriteLinesToNewFile_LinesAreWritten(params string[] content)
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+
+ //act
+ Assert.IsFalse(file.Exists);
+ file.WriteLines(content, Encoding.Unicode);
+ var actual = file.EnumerateLines(Encoding.Unicode).ToArray();
+
+ //assert
+ Assert.AreEqual(content.Length, actual.Length);
+ for (int i = 0; i < content.Length; i++)
+ {
+ Assert.AreEqual(content[i], actual[i]);
+ }
+ }
+
+ [TestCase("line1", "line2", "line3")]
+ [TestCase("line1", "", "line3")]
+ public void WriteLinesWithUTF16Encoding_WriteLinesToExistingFileWithOverwriteDisabled_ThrowsIOException(params string[] content)
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+ file.Truncate();
+
+ //act & assert
+ Assert.IsTrue(file.Exists);
+ //call WriteLines with both overwrite parameter ommitted or set to false
+ var ex1 = Assert.Throws(() => file.WriteLines(content, Encoding.Unicode));
+ var ex2 = Assert.Throws(() => file.WriteLines(content, Encoding.Unicode, false));
+
+ Assert.IsTrue(ex1.Message.Contains(file.FullName));
+ Assert.IsTrue(ex2.Message.Contains(file.FullName));
+ }
+
+ [TestCase("line1", "line2", "line3")]
+ [TestCase("line1", "", "line3")]
+ public void WriteLinesWithUTF16Encoding_WriteLinesToExistingFileWithOverwriteEnabled_FileIsTruncatedAndLinesAreWritten(params string[] content)
+ {
+ //arrange
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+
+ //create file with long content
+ var data = Encoding.Unicode.GetBytes("line5 line4 line3 line2 line1");
+ using (var stream = file.OpenWrite())
+ {
+ stream.Write(data, 0, data.Length);
+ stream.Dispose();
+ }
+
+ //act
+ Assert.IsTrue(file.Exists);
+ file.WriteLines(content, Encoding.Unicode, overwrite: true);
+ var actual = file.EnumerateLines(Encoding.Unicode).ToArray();
+
+ //assert
+ Assert.AreEqual(content.Length, actual.Length);
+ for (int i = 0; i < content.Length; i++)
+ {
+ Assert.AreEqual(content[i], actual[i]);
+ }
+ }
+
+ [TestCase("line1", "line2", "line3")]
+ [TestCase("line1", "", "line3")]
+ public void AppendText_FileExistsAndHasText_LinesAreAppended(params string[] append)
+ {
+ //arrange
+ var initial = new[] { "test1", "test2", "test3" };
+ var fs = new FileSystem();
+ var current = fs.DirectoryInfo.New(fs.Directory.GetCurrentDirectory());
+ var guid = Guid.NewGuid().ToString();
+ var file = current.File(guid);
+ file.WriteLines(initial);
+
+ //act
+ file.AppendLines(append);
+
+ //assert
+ var expected = initial.Concat(append).ToArray();
+ var actual = file.EnumerateLines().ToArray();
+
+ Assert.AreEqual(expected.Length, actual.Length);
+ for (int i = 0; i < expected.Length; i++)
+ {
+ Assert.AreEqual(expected[i], actual[i]);
+ }
+ }
}
-}
+}
\ No newline at end of file