File.ReadAllLines
は存在しますが、Stream.ReadAllLines
は存在しません。
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt"))
using (StreamReader reader = new StreamReader(stream))
{
// Would prefer string[] result = reader.ReadAllLines();
string result = reader.ReadToEnd();
}
これを行う方法はありますか、またはファイルを1行ずつ手動でループする必要がありますか?
次のように、行ごとに読み取るメソッドを作成できます。
public IEnumerable<string> ReadLines(Func<Stream> streamProvider,
Encoding encoding)
{
using (var stream = streamProvider())
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
次に、次のように呼び出します。
var lines = ReadLines(() => Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName),
Encoding.UTF8)
.ToList();
Func<>
パートは、複数回読み取るときに対処し、ストリームを不必要に開いたままにしないようにすることです。もちろん、そのコードをメソッドに簡単にラップできます。
一度にすべてをメモリに保存する必要がない場合は、ToList
...も必要ありません。
.EndOfStream
プロパティは、次の行がnullでないかどうかをチェックする代わりに、ループで使用できます。
List<string> lines = new List<string>();
using (StreamReader reader = new StreamReader("example.txt"))
{
while(!reader.EndOfStream)
{
lines.Add(reader.ReadLine());
}
}
ここでのSplit
の使用:
reader
.ReadToEnd()
.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
ReadLine
と同等ではありません。 ReadLine
、 StreamReader.cs のソースを見ると、行終端文字(\ r、\ n、および\ r\n)を正しく処理していることがわかります。 ReadLine
は、行末記号が\ r\nの場合、余分な空の文字列を返しません。これはDOS/Windowsで一般的です。 Split
は、\ rの後に2つの個別の区切り文字として「見える」(解析する)もので、空の文字列を返します。
上記のコードの「StringSplitOptions.RemoveEmptyEntries」はこれらの空の文字列を削除しますが、入力に表示される空の行も削除します。
したがって、入力に対してline1\r\r line3\r ReadLine
は3行を返します。 2番目は空です。 Split
は4つの文字列を作成します。 (最後の\ rの後に追加の文字列があります。)2番目と4番目を削除します。
Split
は、「修正後」で区切られたテキスト行の解析にはあまり適していません。それは、トークンの後に表示される区切り文字です。 Split
は中置に適していますが、区切り文字はトークン間にあります。これは、a、b、cとline1\r、line2、line3\rの違いです。これらの入力に対して、Split
はそれぞれ3つの文字列または4つの文字列を返します。
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt"))
using (StreamReader reader = new StreamReader(stream))
{
// Would prefer string[] result = reader.ReadAllLines();
string[] result = reader.ReadToEnd().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
次の拡張メソッドを使用します。
public static class Extensions
{
public static IEnumerable<string> ReadAllLines(this StreamReader reader)
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
目的のコードに到達することが可能です。
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Test_Resources.Resources.Accounts.txt"))
using (StreamReader reader = new StreamReader(stream))
{
string[] result = reader.ReadAllLines().ToArray();
}
StreamReaderを使用する場合は、ReadLineを使用してStreamReaderをループ処理し、1行ずつ読み取る必要があります。
そんな感じ:
string line;
using (StreamReader reader = new StreamReader(stream))
{
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
または試す
using (StreamReader reader = new StreamReader("file.txt"))
{
string[] content = reader.ReadToEnd().Replace("\n","").Split('\t');
}