Skip to content

Commit

Permalink
Merge pull request #1492 from glopesdev/text-io
Browse files Browse the repository at this point in the history
Add ReadAllText and WriteAllText operators
  • Loading branch information
glopesdev authored Jul 25, 2023
2 parents 2c04258 + 70a8520 commit 1cdbe76
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
36 changes: 36 additions & 0 deletions Bonsai.System/IO/ReadAllText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Reactive.Linq;

namespace Bonsai.IO
{
/// <summary>
/// Represents an operator that opens a text file, returns a single string with all
/// lines in the file, and then closes the file.
/// </summary>
[DefaultProperty(nameof(Path))]
[Description("Opens a text file, returns a single string with all lines in the file, and then closes the file.")]
public class ReadAllText : Source<string>
{
/// <summary>
/// Gets or sets the relative or absolute path of the file to open for reading.
/// </summary>
[Description("The relative or absolute path of the file to open for reading.")]
[Editor("Bonsai.Design.OpenFileNameEditor, Bonsai.Design", DesignTypes.UITypeEditor)]
public string Path { get; set; }

/// <summary>
/// Generates an observable sequence that opens the text file, returns a single string
/// with all lines in the file, and then closes the file.
/// </summary>
/// <returns>
/// A sequence containing a single string with all lines in the file.
/// </returns>
public override IObservable<string> Generate()
{
var path = Path;
return Observable.Defer(() => Observable.Return(File.ReadAllText(path)));
}
}
}
64 changes: 64 additions & 0 deletions Bonsai.System/IO/WriteAllText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Reactive.Linq;

namespace Bonsai.IO
{
/// <summary>
/// Represents an operator that opens a text file, writes the source string to
/// the file, and then closes the file.
/// </summary>
[DefaultProperty(nameof(Path))]
[Description("Creates a new file, writes the source string to the file, and then closes the file.")]
public class WriteAllText : Sink<string>
{
/// <summary>
/// Gets or sets the relative or absolute path of the file to open for writing.
/// </summary>
[Description("The relative or absolute path of the file to open for writing.")]
[Editor("Bonsai.Design.SaveFileNameEditor, Bonsai.Design", DesignTypes.UITypeEditor)]
public string Path { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the output file should be overwritten if it already exists.
/// </summary>
[Description("Indicates whether the output file should be overwritten if it already exists.")]
public bool Overwrite { get; set; }

/// <summary>
/// Gets or sets a value indicating whether text should be appended to the output file if it already exists.
/// </summary>
[Description("Indicates whether text should be appended to the output file if it already exists.")]
public bool Append { get; set; }

/// <summary>
/// Creates a new file, writes the string in the observable sequence to the file,
/// and then closes the file.
/// </summary>
/// <param name="source">
/// The sequence containing the string to write to the file.
/// </param>
/// <returns>
/// An observable sequence that is identical to the <paramref name="source"/> sequence
/// but where there is an additional side effect of writing the string to the file.
/// </returns>
public override IObservable<string> Process(IObservable<string> source)
{
var path = Path;
var overwrite = Overwrite;
var append = Append;
return source.Do(contents =>
{
PathHelper.EnsureDirectory(path);
if (File.Exists(path) && !overwrite && !append)
{
throw new IOException($"The file '{path}' already exists.");
}
using var writer = new StreamWriter(path, append);
writer.Write(contents);
});
}
}
}

0 comments on commit 1cdbe76

Please sign in to comment.