Skip to content

Commit b662113

Browse files
author
Daniel Kaluski
committed
Added 'Create target directories' option to Write and WriteBytes
1 parent 1afb296 commit b662113

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

Frends.File.Tests/UnitTest.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,39 @@ public async Task WriteFileThrow()
361361
Assert.Equal("old content", fileContent);
362362
Assert.Equal($"File already exists: {Path.Combine(TestFileContext.RootPath, "test.txt")}", ex.Message);
363363
}
364+
[Fact]
365+
public async Task WriteFileCreateDirectory()
366+
{
367+
var result = await File.Write(
368+
new WriteInput()
369+
{
370+
Content = "Created with a subdirectory",
371+
Path = Path.Combine(TestFileContext.RootPath, "folder/Subdir/subdir.txt")
372+
},
373+
new WriteOption()
374+
{
375+
CreateTargetDirectories = true
376+
});
377+
var fileContent = System.IO.File.ReadAllText(result.Path);
378+
Console.WriteLine(result.Path);
379+
Assert.Equal("Created with a subdirectory", fileContent);
380+
}
381+
382+
[Fact]
383+
public async Task WriteFileCreateDirectoryThrow()
384+
{
385+
var result = await Assert.ThrowsAsync<DirectoryNotFoundException>(async () => await File.Write(
386+
new WriteInput()
387+
{
388+
Content = "Task should throw",
389+
Path = Path.Combine(TestFileContext.RootPath, "folder/Subdir/subdir.txt")
390+
},
391+
new WriteOption()
392+
{
393+
CreateTargetDirectories = false
394+
}));
395+
396+
}
364397

365398
[Fact]
366399
public async Task WriteFileBytesAppend()
@@ -430,6 +463,42 @@ public async Task WriteFileBytesThrow()
430463
Assert.Equal(imageBytes, fileContentBytes);
431464
}
432465

466+
[Fact]
467+
public async Task WriteFileBytesCreateDirectory()
468+
{
469+
var imageBytes = System.IO.File.ReadAllBytes(BinaryTestFilePath);
470+
TestFileContext.CreateBinaryFile("test.png", new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }); // empty png
471+
var result = await File.WriteBytes(
472+
new WriteBytesInput()
473+
{
474+
ContentBytes = imageBytes,
475+
Path = Path.Combine(TestFileContext.RootPath, "folder/Subdir/test.png")
476+
},
477+
new WriteBytesOption()
478+
{
479+
CreateTargetDirectories = true,
480+
});
481+
var fileContentBytes = System.IO.File.ReadAllBytes(result.Path);
482+
Assert.Equal(imageBytes.Length, fileContentBytes.Length);
483+
Assert.Equal(imageBytes, fileContentBytes);
484+
}
485+
[Fact]
486+
public async Task WriteFileBytesCreateDirectoryThrow()
487+
{
488+
var imageBytes = System.IO.File.ReadAllBytes(BinaryTestFilePath);
489+
TestFileContext.CreateBinaryFile("test.png", new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }); // empty png
490+
var result = await Assert.ThrowsAsync<DirectoryNotFoundException>(async () => await File.WriteBytes(
491+
new WriteBytesInput()
492+
{
493+
ContentBytes = imageBytes,
494+
Path = Path.Combine(TestFileContext.RootPath, "folder/Subdir/test.png")
495+
},
496+
new WriteBytesOption()
497+
{
498+
CreateTargetDirectories = false,
499+
}));
500+
}
501+
433502
[Fact]
434503
public async Task ReadFileContent()
435504
{

Frends.File/Definitions.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,13 @@ public class WriteOption
247247
/// How the file write should work if a file with the new name already exists
248248
/// </summary>
249249
public WriteBehaviour WriteBehaviour { get; set; }
250+
251+
/// <summary>
252+
/// If set, will create the target directory if it does not exist,
253+
/// as well as any sub directories.
254+
/// </summary>
255+
[DefaultValue(false)]
256+
public bool CreateTargetDirectories { get; set; }
250257
}
251258

252259
public class WriteBytesOption
@@ -273,6 +280,13 @@ public class WriteBytesOption
273280
/// How the file write should work if a file with the new name already exists
274281
/// </summary>
275282
public WriteBehaviour WriteBehaviour { get; set; }
283+
284+
/// <summary>
285+
/// If set, will create the target directory if it does not exist,
286+
/// as well as any sub directories.
287+
/// </summary>
288+
[DefaultValue(false)]
289+
public bool CreateTargetDirectories { get; set; }
276290
}
277291

278292
public class WriteResult

Frends.File/File.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ private static async Task<WriteResult> ExecuteWrite(WriteInput input, WriteOptio
287287
var encoding = GetEncoding(options.FileEncoding, options.EnableBom, options.EncodingInString);
288288
var fileMode = GetAndCheckWriteMode(options.WriteBehaviour, input.Path);
289289

290+
if(options.CreateTargetDirectories)
291+
{
292+
var directoryPath = Path.GetDirectoryName(input.Path);
293+
if(!Directory.Exists(directoryPath))
294+
{
295+
Directory.CreateDirectory(directoryPath);
296+
}
297+
}
298+
290299
using (var fileStream = new FileStream(input.Path, fileMode, FileAccess.Write, FileShare.Write, 4096, useAsync: true))
291300
using (var writer = new StreamWriter(fileStream, encoding))
292301
{
@@ -298,6 +307,14 @@ private static async Task<WriteResult> ExecuteWrite(WriteInput input, WriteOptio
298307

299308
private static async Task<WriteResult> ExecuteWriteBytes(WriteBytesInput input, WriteBytesOption options)
300309
{
310+
if (options.CreateTargetDirectories)
311+
{
312+
var directoryPath = Path.GetDirectoryName(input.Path);
313+
if (!Directory.Exists(directoryPath))
314+
{
315+
Directory.CreateDirectory(directoryPath);
316+
}
317+
}
301318
var bytes = input?.ContentBytes as byte[] ?? throw new ArgumentException("Input.ContentBytes must be a byte array", nameof(input.ContentBytes)); // TODO: Use corrctly typed input once UI support expression default editor for arrays
302319

303320
var fileMode = GetAndCheckWriteMode(options.WriteBehaviour, input.Path);

0 commit comments

Comments
 (0)