例えばテキストファイルから末尾の1行だけを削除したいとか、テキストファイルの先頭に1行追加したいという場合は、1発で解決できる方法がありません。基本的には、「文字コードを指定してテキストファイルを読み込む」で紹介している方法でテキストファイルを読み込み、1行削除(あるいは追加)してから、「文字コードを指定してテキストファイルに書き込む」で紹介している方法で上書きするという方法になります。ここではその方法を、具体例を示して説明します。
なおテキストファイルの末尾に1行追加する場合は、「既存のファイルに追加で書き込む」の方法で簡単にできます。
まずは、テキストファイルの内容をすべて読み込んでから、文字列を編集して、編集結果をテキストファイルに書き込む方法を考えてみます。
下の例では、テキストファイル「C:\test\1.txt」の先頭に1行追加しています。この例ではFile.ReadAllTextとWriteAllTextメソッドを使用していますので、.NET Framework 2.0以降が必要です。
'ファイルのパス Dim filePath As String = "C:\test\1.txt" 'テキストファイルからすべて読み込む Dim str As String = System.IO.File.ReadAllText(filePath) '先頭に1行追加する str = "新しい行です。" & vbCrLf & str 'テキストファイルに上書き保存する System.IO.File.WriteAllText(filePath, str)
//ファイルのパス string filePath = @"C:\test\1.txt"; //テキストファイルからすべて読み込む string str = System.IO.File.ReadAllText(filePath); //先頭に1行追加する str = "新しい行です。\r\n" + str; //テキストファイルに上書き保存する System.IO.File.WriteAllText(filePath, str);
次に、テキストファイルの末尾から1行削除する例を示します。この場合も前の例と同じように文字列を編集することで削除してもよいのですが、ここではテキストファイルの内容を配列で取得して、Enumerable.Takeメソッドで行を削除する方法を紹介します。このコードを実行させるには、.NET Framework 3.5以降が必要です。なお配列の長さを変更する方法は他にもたくさんあり、「配列の大きさを変える」で紹介しています。
'Imports System.Linq 'ファイルのパス Dim filePath As String = "C:\test\1.txt" 'テキストファイルからすべての行を読み込む Dim lines As String() = System.IO.File.ReadAllLines(filePath) '最後の1行を削除する lines = lines.Take(lines.Length - 1).ToArray() '最初の1行を削除するなら、次のようにする 'lines = lines.Skip(1).ToArray(); 'テキストファイルに上書き保存する System.IO.File.WriteAllLines(filePath, lines)
//using System.Linq; //ファイルのパス string filePath = @"C:\test\1.txt"; //テキストファイルからすべての行を読み込む string[] lines = System.IO.File.ReadAllLines(filePath); //最後の1行を削除する lines = lines.Take(lines.Length - 1).ToArray(); //最初の1行を削除するなら、次のようにする //lines = lines.Skip(1).ToArray(); //テキストファイルに上書き保存する System.IO.File.WriteAllLines(filePath, lines);
今までの例では、ファイルを読み込む時と書き込む時の2回開いています。同じファイルに読み込みと書き込みを行うためにファイルを2度開く必要はなく、1度で済ますこともできます。ファイルを1度だけ開くようにすれば、ファイルを読み込んでから書き込むまでの間にファイル内容が変更されてしまうことを防ぐこともできます。
下の例では、一番初めのサンプルと同じことをこの方法で行っています。
'テキストファイルのパス Dim filePath As String = "C:\test\1.txt" '書き込みと読み込みが可能なようにファイルを開く Dim fs As New System.IO.FileStream(filePath, _ System.IO.FileMode.Open, _ System.IO.FileAccess.ReadWrite, _ System.IO.FileShare.None) 'FileStreamを基にして、StreamReaderを作成する Dim sr As New System.IO.StreamReader(fs) 'FileStreamを基にして、StreamWriterを作成する Dim sw As New System.IO.StreamWriter(fs) 'テキストファイルからすべて読み込む Dim str As String = sr.ReadToEnd() '先頭に1行追加する str = "新しい行です。" & vbCrLf & str '位置を先頭にする fs.Position = 0 '長さを0にする fs.SetLength(0) '書き込む sw.Write(str) sw.Flush() '閉じる sr.Close() '(StreamWriter.Closeは基になるStreamが閉じた後に呼び出すと、 ' 例外ObjectDisposedExceptionをスローする) If sw.BaseStream.CanWrite Then sw.Close() End If fs.Close()
//テキストファイルのパス string filePath = @"C:\test\1.txt"; //書き込みと読み込みが可能なようにファイルを開く System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None); //FileStreamを基にして、StreamReaderを作成する System.IO.StreamReader sr = new System.IO.StreamReader(fs); //FileStreamを基にして、StreamWriterを作成する System.IO.StreamWriter sw = new System.IO.StreamWriter(fs); //テキストファイルからすべて読み込む string str = sr.ReadToEnd(); //先頭に1行追加する str = "新しい行です。\r\n" + str; //位置を先頭にする fs.Position = 0; //長さを0にする fs.SetLength(0); //書き込む sw.Write(str); sw.Flush(); //閉じる sr.Close(); //(StreamWriter.Closeは基になるStreamが閉じた後に呼び出すと、 // 例外ObjectDisposedExceptionをスローする) if (sw.BaseStream.CanWrite) { sw.Close(); } fs.Close();
上記の方法では一度にテキストファイルの内容をすべて読み込むため、サイズの大きなテキストファイルの場合、負担が大きくなります。そのような場合は、テキストファイルから1行ずつ読み込み、1行ずつ書き込んだ方がよいでしょう。この時、1つのファイルに読み込みと書き込みを同時に行うこともできますが、とても面倒なので、ここでは書き込み先は一時ファイルとしておき、最後にファイルを入れ替えるという方法でやってみます。
以下の例では、この方法でテキストファイルの先頭の1行を削除しています。
'ファイルのパス Dim filePath As String = "C:\test\1.txt" 'ファイルを読み込みで開く Dim sr As New System.IO.StreamReader(filePath) '一時ファイルを作成する Dim tmpPath As String = System.IO.Path.GetTempFileName() '一時ファイルを書き込みで開く Dim sw As New System.IO.StreamWriter(tmpPath) Dim isFirstLine As Boolean = True '内容を一行ずつ読み込む While sr.Peek() > -1 '一行読み込む Dim line As String = sr.ReadLine() 'はじめの行であれば、飛ばす If isFirstLine Then isFirstLine = False Continue While End If '一時ファイルに書き込む sw.WriteLine(line) End While '閉じる sr.Close() sw.Close() '一時ファイルと入れ替える System.IO.File.Copy(tmpPath, filePath, True) System.IO.File.Delete(tmpPath)
//ファイルのパス string filePath = @"C:\test\1.txt"; //ファイルを読み込みで開く System.IO.StreamReader sr = new System.IO.StreamReader(filePath); //一時ファイルを作成する string tmpPath = System.IO.Path.GetTempFileName(); //一時ファイルを書き込みで開く System.IO.StreamWriter sw = new System.IO.StreamWriter(tmpPath); bool isFirstLine = true; //内容を一行ずつ読み込む while (sr.Peek() > -1) { //一行読み込む string line = sr.ReadLine(); //はじめの行であれば、飛ばす if (isFirstLine) { isFirstLine = false; continue; } //一時ファイルに書き込む sw.WriteLine(line); } //閉じる sr.Close(); sw.Close(); //一時ファイルと入れ替える System.IO.File.Copy(tmpPath, filePath, true); System.IO.File.Delete(tmpPath);
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。