web-dev-qa-db-ja.com

Javaを介して既存のファイルにテキストを挿入する

テキストファイルを編集する簡単なプログラム(Java)を作成したいと思います。特に、テキストファイルのランダムな位置に任意のテキストを挿入するプログラムを作成します。この機能は、私が現在書いているより大きなプログラムの一部です。

Java.util.RandomAccessFileに関する説明を読むと、ファイルの途中で実行された書き込み操作は、実際には既存のコンテンツを上書きするように見えます。これは私が避けたい副作用です(可能な場合)。

これを達成する簡単な方法はありますか?

前もって感謝します。

24
Dinuk

さて、この質問はかなり古いですが、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();
}
16
xor_eq

まあ、いいえ、既存のコンテンツを単一の標準のJava IO API呼び出しで上書きすることを回避する方法があるとは思いません。

ファイルが大きすぎない場合は、ファイル全体をArrayList(行ごとのエントリ)に読み込み、エントリを書き換えるか、新しい行に新しいエントリを挿入します。

次に、既存のファイルを新しいコンテンツで上書きするか、既存のファイルをバックアップに移動して新しいファイルを書き込みます。

どの程度高度な編集が必要かによって、データ構造を変更する必要がある場合があります。

別の方法は、編集されたファイルへの書き込み中に既存のファイルから文字を読み取り、読み取られたストリームを編集することです。

11
Ken Gentle

Javaにファイルをメモリマップする方法がある場合、ファイルを新しい長さに拡張し、ファイルをマップし、すべてのバイトを最後までメモしてホールを作成し、新しいデータを穴に書き込みます。

これはCで動作します。Javaで試したことはありません。

私が同じことをすることを考えた別の方法ですが、ランダムなファイルアクセスがあります。

  • 最後までシーク-1 MB
  • 1MBを読む
  • それを元の位置+ギャップサイズに書き込みます。
  • ファイルの先頭に向かって作業する前の1 MBごとに繰り返します。
  • 希望のギャップ位置に到達したら停止します。

パフォーマンスを向上させるには、より大きなバッファサイズを使用します。

4
Zan Lynx

次のコードを使用できます。

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);
}
4
S.Yavari

既存のテキストファイルにテキストを挿入する唯一の方法は、元のファイルを読み取り、新しいテキストが挿入された一時ファイルにコンテンツを書き込むことです。次に、元のファイルを消去し、一時ファイルの名前を元の名前に変更します。

この は、既存のファイルに1行を挿入することに焦点を当てていますが、それでもおそらく役立つでしょう。

2
Brendan Cashman

それ以外にまっすぐに行うための便利な方法があるかどうかはわかりません

  • ファイルの先頭を読み取り、ターゲットに書き込みます
  • ターゲットに新しいテキストを書きます
  • ファイルの残りの部分を読み取り、それをターゲットに書き込みます。

ターゲットについて:処理するファイルがそれほど大きくない場合は、メモリ内にファイルの新しいコンテンツを作成し、ファイルの古いコンテンツを上書きできます。または、結果を一時ファイルに書き込むことができます。

RandomAccessFileは、途中で挿入するためのものではないようです(afaik)。必要に応じて tutorial を確認してください。

2
Touko

それがテキストファイルの場合は、既存のファイルをStringBufferで読み取り、新しいコンテンツを同じStringBufferに追加すると、ファイルにSrtingBufferを書き込むことができます。これで、ファイルには既存のテキストと新しいテキストの両方が含まれます。

0
saravana kumar