テキストファイルを編集する簡単なプログラム(Java)を作成したいと思います。特に、テキストファイルのランダムな位置に任意のテキストを挿入するプログラムを作成します。この機能は、私が現在書いているより大きなプログラムの一部です。
Java.util.RandomAccessFileに関する説明を読むと、ファイルの途中で実行された書き込み操作は、実際には既存のコンテンツを上書きするように見えます。これは私が避けたい副作用です(可能な場合)。
これを達成する簡単な方法はありますか?
前もって感謝します。
さて、この質問はかなり古いですが、FileChannelはJava 1.4以降に存在し、ファイル内のコンテンツの置換または挿入の問題を処理するときになぜ言及されないのかわかりません。 FileChannels は高速です。使用してください。
以下に例を示します(例外やその他のものを無視します):
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(行ごとのエントリ)に読み込み、エントリを書き換えるか、新しい行に新しいエントリを挿入します。
次に、既存のファイルを新しいコンテンツで上書きするか、既存のファイルをバックアップに移動して新しいファイルを書き込みます。
どの程度高度な編集が必要かによって、データ構造を変更する必要がある場合があります。
別の方法は、編集されたファイルへの書き込み中に既存のファイルから文字を読み取り、読み取られたストリームを編集することです。
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)。必要に応じて tutorial を確認してください。
それがテキストファイルの場合は、既存のファイルをStringBufferで読み取り、新しいコンテンツを同じStringBufferに追加すると、ファイルにSrtingBufferを書き込むことができます。これで、ファイルには既存のテキストと新しいテキストの両方が含まれます。