テキストファイルの最終行から指定行数だけ読み出して返します。
バッファやポジションの扱いは苦手で、もう一度書きたくなかったので残します。
- 本記事のすべての情報は利用者の責任において利用ください。
- 本記事の情報が正しいこと、誤っていることと実行効率を検証していません。
- 動作することも、動作しないことも保証しません。
誤りや改善案はご指摘いただければ感謝します。が、修正できない場合があることをご了承ください。
Program.cs
internal class Program
{
static void Main(string[] _)
{
Console.Write(
ReadTailLines(
@"C:\temp\新規 テキスト ドキュメント.txt",
Encoding.UTF8,
3
));
}
static string? ReadTailLines(
string filePath,
Encoding encoding,
int lineCount,
int bufferBytes = 10,
string delimiter = "\r\n"
)
{
using FileStream stream = new(
filePath,
FileMode.Open,
FileAccess.Read
);
return ReadTailLines(stream, encoding, lineCount, bufferBytes, delimiter);
}
static string? ReadTailLines(
FileStream stream,
Encoding encoding,
int lineCount,
int bufferBytes = 10,
string delimiter = "\r\n"
)
{
if (bufferBytes <= 0) throw new ArgumentException($"bufferBytes <= 0");
if (string.IsNullOrEmpty(delimiter)) throw new ArgumentException($"empty delimiter");
Stack<IEnumerable<byte>> stack = new();
// 読み出すバイト数
int readBytes = (int)Math.Min(bufferBytes, stream.Length);
stream.Position = stream.Length - readBytes;
while (stream.Position >= 0 && readBytes > 0)
{
var buffer = new byte[readBytes];
if (stream.Read(buffer, 0, readBytes) > 0)
{
// 読み出したバイト列の評価
{
stack.Push(buffer);
var s = encoding.GetString(
stack.SelectMany(x => x).ToArray()
).TrimEnd();
var lastIndex = s.LastIndexOfTimes(delimiter, lineCount);
if (lastIndex > -1)
{
return s[(lastIndex + delimiter.Length)..];
}
}
// 次の周回の Position 合わせ
{
int beforeReadPosition = (int)stream.Position - readBytes;
readBytes = (beforeReadPosition - bufferBytes >= 0)
? bufferBytes
: beforeReadPosition;
stream.Position = beforeReadPosition - readBytes;
}
}
}
return null;
}
}
StringExtension.cs
static class StringExtension
{
public static int LastIndexOfTimes(this string self, string search, int times)
{
int foundCount = 0;
int index = self.LastIndexOf(search, self.Length - 1);
while (index > -1)
{
foundCount++;
if (foundCount >= times)
{
return index;
}
else
{
index = self.LastIndexOf(search, index);
}
}
return -1;
}
}
新規 テキスト ドキュメント.txt
A,B,C,D,E
F,G,H,I,J,K,L,M,N,O,P,Q,R,
ぎゃはS,T,U,V,W,X,Y,Z
出力
F,G,H,I,J,K,L,M,N,O,P,Q,R,
ぎゃはS,T,U,V,W,X,Y,Z
確認した環境
- Windows 11 Home 22H2
- Microsoft Visual Studio Community 2022 (64 ビット) Version 17.4.3
- .NET Core 6.0
関連記事