テキストファイルを編集する簡単なプログラム(Javaで)を作成したいと思います。特に、テキストファイルのランダムな位置に任意のテキストを挿入するプログラムです。この機能は、私が現在書いているより大きなプログラムの一部です。
java.util.RandomAccessFile に関する説明を読むと、ファイルの途中で書き込み操作を実行すると、既存のコンテンツが実際に上書きされるようです。これは、(可能であれば)避けたい副作用です。
これを達成する簡単な方法はありますか?
前もって感謝します。
テキストファイルを編集する簡単なプログラム(Javaで)を作成したいと思います。特に、テキストファイルのランダムな位置に任意のテキストを挿入するプログラムです。この機能は、私が現在書いているより大きなプログラムの一部です。
java.util.RandomAccessFile に関する説明を読むと、ファイルの途中で書き込み操作を実行すると、既存のコンテンツが実際に上書きされるようです。これは、(可能であれば)避けたい副作用です。
これを達成する簡単な方法はありますか?
前もって感謝します。
さて、この質問はかなり古いですが、FileChannels は Java 1.4 から存在し、ファイルのコンテンツを置換または挿入する問題を扱うときに、なぜどこにも言及されていないのかわかりません。FileChannelは高速です。使用してください。
以下に例を示します (例外やその他のものは無視します)。
public void insert(String filename, long offset, byte[] content) {
RandomAccessFile r = new RandomAccessFile(new File(filename), "rw");
RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw");
long fileSize = r.length();
FileChannel sourceChannel = r.getChannel();
FileChannel targetChannel = rtemp.getChannel();
sourceChannel.transferTo(offset, (fileSize - offset), targetChannel);
sourceChannel.truncate(offset);
r.seek(offset);
r.write(content);
long newOffset = r.getFilePointer();
targetChannel.position(0L);
sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset));
sourceChannel.close();
targetChannel.close();
}
いいえ、単一の標準 Java IO API 呼び出しで既存のコンテンツを上書きしないようにする方法があるとは思いません。
ファイルが大きすぎない場合は、ファイル全体を ArrayList (行ごとのエントリ) に読み込み、エントリを書き換えるか、新しい行に新しいエントリを挿入します。
次に、既存のファイルを新しいコンテンツで上書きするか、既存のファイルをバックアップに移動して新しいファイルを書き込みます。
編集の高度さに応じて、データ構造を変更する必要がある場合があります。
もう 1 つの方法は、編集済みファイルへの書き込み中に既存のファイルから文字を読み取り、読み取り時にストリームを編集することです。
Javaにファイルをメモリマップする方法がある場合は、ファイルを新しい長さに拡張し、ファイルをマップし、すべてのバイトを最後までメモして穴を開け、新しいデータを穴に書き込むことができます。
これはCで動作します。Javaで試したことはありません。
同じことをランダムなファイルアクセスで行うことを考えた別の方法。
パフォーマンスを高速化するには、より大きなバッファサイズを使用してください。
次のコードを使用できます。
BufferedReader reader = null;
BufferedWriter writer = null;
ArrayList list = new ArrayList();
try {
reader = new BufferedReader(new FileReader(fileName));
String tmp;
while ((tmp = reader.readLine()) != null)
list.add(tmp);
OUtil.closeReader(reader);
list.add(0, "Start Text");
list.add("End Text");
writer = new BufferedWriter(new FileWriter(fileName));
for (int i = 0; i < list.size(); i++)
writer.write(list.get(i) + "\r\n");
} catch (Exception e) {
e.printStackTrace();
} finally {
OUtil.closeReader(reader);
OUtil.closeWriter(writer);
}
既存のテキスト ファイルにテキストを挿入する唯一の方法は、元のファイルを読み取り、新しいテキストが挿入された一時ファイルにコンテンツを書き込むことだと思います。次に、元のファイルを消去し、一時ファイルの名前を元の名前に変更します。
この例は、既存のファイルに 1 行を挿入することに焦点を当てていますが、それでも役に立つかもしれません。
それ以外の方法で直接行う便利な方法があるかどうかはわかりません
ターゲットについて : ファイルの新しい内容をメモリ内に構築し、処理するファイルがそれほど大きくない場合は、ファイルの古い内容を上書きできます。または、結果を一時ファイルに書き込むことができます。
おそらくストリームで行うのが最も簡単でしょう.RandomAccessFileは途中で挿入することを意図していないようです(afaik)。必要に応じてチュートリアルを確認してください。
テキスト ファイルの場合、、、、StringBuffer 内の既存のファイルを読み取り、同じ StringBuffer に新しいコンテンツを追加すると、ファイルに SrtingBuffer を書き込むことができます。そのため、ファイルには既存のテキストと新しいテキストの両方が含まれています。