2009-05-04 14 views
26

Javaを使用して編集したいテキストファイルがあります。それは何千もの行を持っています。私は基本的に行を繰り返し、いくつかのテキストを変更/編集/削除したいと思っています。これはかなり頻繁に起こる必要があります。Javaで.txtファイルを変更します。

私は他のサイトで見たソリューションから、一般的なアプローチがあるように思わ:

  • オープンBufferedReaderの
  • を使用して、既存のファイルは、それぞれの行を読んで、各ラインに変更を加えると、それを追加StringBuilderの
  • すべてのテキストを読んで、変更されていたら、
  • 新しいファイルにのStringBuilderの内容を書き込む新しいファイル
と古いファイルを置き換え

このソリューションは、私のテキストファイルに何千もの行がある場合、私にとってはちょっとハックしたようです。

もっと良い解決法を知っている人はいますか?

+0

JavaのRandomAccessFileを使用して、ファイル全体を書き戻さずにファイルを変更できます。私が投稿した以下の詳細情報を参照してください。 – sendon1982

答えて

29

私は最近Javaでこれを行っていませんが、ファイル全体をメモリに書き込むことは悪い考えです。

私が思いつくことができる最良のアイデアは、同時に書き込みモードで一時ファイルを開き、それを読み、必要に応じて変更して、一時ファイルに書き込むことです。最後に、元のファイルを削除して一時ファイルの名前を変更します。

ファイルシステムの変更権限を持っている場合は、削除権限と名前の変更権限も必要です。

+1

私の答えは間違っていました。私はRandomAccessFileが挿入や削除を許可しないことを忘れていました。私はこれが最高の答えだと思います。 –

+0

私はこのアプローチをBufferedReaderとBufferedWriterで使い終わった。 –

2

ファイルが大きい場合、出力にFileStreamを使用することができますが、それはあなたが求めていることを行う最も簡単なプロセスであるようです(そして、編集/削除を実行すると、より複雑な方法が何であるかを判断することは不可能です)。

1

通常、ファイルを編集することはできません。これは単なる非常に長い文字列であり、改行文字を含むことになります。変更によって各行の文字数が変更されない場合は、その場で編集できます。

2

ファイル全体をバッファリングする理由はありません。

必要に応じて行を挿入し、必要に応じて行を削除し、必要に応じて行を置き換えます。

特に唯一のテキストファイルの場合は、ファイルの卸売りを再作成する必要はありません。

2

どのような種類のデータですか?あなたはファイルのフォーマットを制御しますか?

ファイルに名前/値のペア(または類似のもの)が含まれている場合は、Propertiesで運が良かったり、フラットファイルのJDBCドライバを使用して何かを共にしたりできます。

また、データを頻繁に書き込まないと考えたことはありますか?ファイルのメモリ内コピーの操作は比較的簡単です。ファイルのリアルタイム更新が必要な外部リソースがない場合は、変更するたびにディスクに移動する必要はありません。スケジュールされたタスクを実行して、データのバックアップが心配な場合に定期的な更新をディスクに書き込むことができます。

5

ファイルがほんの数千行の場合は、ファイル全体を1つの読み込みで読み込み、それを文字列に変換できるはずです。

Apache IOUtilsは、次のようなメソッドを使用できます。

public static String readFile(String filename) throws IOException { 
    File file = new File(filename); 
    int len = (int) file.length(); 
    byte[] bytes = new byte[len]; 
    FileInputStream fis = null; 
    try { 
     fis = new FileInputStream(file); 
     assert len == fis.read(bytes); 
    } catch (IOException e) { 
     close(fis); 
     throw e; 
    } 
    return new String(bytes, "UTF-8"); 
} 

public static void writeFile(String filename, String text) throws IOException { 
    FileOutputStream fos = null; 
    try { 
     fos = new FileOutputStream(filename); 
     fos.write(text.getBytes("UTF-8")); 
    } catch (IOException e) { 
     close(fos); 
     throw e; 
    } 
} 

public static void close(Closeable closeable) { 
    try { 
     closeable.close(); 
    } catch(IOException ignored) { 
    } 
} 
1

変更したいことがわかっている場合は、正規表現を使用できませんか? Jakarta Regexpはおそらくトリックを行うべきです。

1

を参照して、多くのことを助ける私はここに私の答えを入れて良いと思います。 このシナリオでは、java.nio.channelsパッケージのFileChannelを使用することをお勧めします。 しかし、これは、あなたが良いパフォーマンスを持つ必要がある場合のみ!あなたはRandomAccessFile経由FileChannelを取得する必要があるだろう、このように:この後

java.nio.channels.FileChannel channel = new java.io.RandomAccessFile("/my/fyle/path", "rw").getChannel();

、あなたはFileChannelから読み込まれますByteBufferを作成する必要があります。

これは、このようなものになります。


java.nio.ByteBuffer inBuffer = java.nio.ByteBuffer.allocate(100); 
int pos = 0; 
int aux = 0; 
StringBuilder sb = new StringBuilder(); 

while (pos != -1) { 

    aux = channel.read(inBuffer, pos); 
    pos = (aux != -1) ? pos + aux : -1; 

    b = inBuffer.array(); 
    sb.delete(0, sb.length()); 

    for (int i = 0; i < b.length; ++i) { 

     sb.append((char)b[i]); 

    } 

    //here you can do your stuff on sb 

    inBuffer = ByteBuffer.allocate(100); 

} 

は、私の答えはあなたを助けることを願っています!

1

JavaのRandomAccessFileを使用して、ある条件でファイルを変更することができます。 各行のサイズを固定する必要があります。そうでない場合は、新しい文字列を書き戻すときに次の行の文字列を上書きする可能性があります。

したがって、私の例では、ファイルを作成してファイルに書き戻すときに、行の長さを100に設定し、空白文字で埋めています。

更新を許可するには、このファイル内の行の長さを最長の長さより少し長く設定する必要があります。

public class RandomAccessFileUtil { 
public static final long RECORD_LENGTH = 100; 
public static final String EMPTY_STRING = " "; 
public static final String CRLF = "\n"; 

public static final String PATHNAME = "/home/mjiang/JM/mahtew.txt"; 

/** 
* one two three 
    Text to be appended with 
    five six seven 
    eight nine ten 
* 
* 
* @param args 
* @throws IOException 
*/ 
public static void main(String[] args) throws IOException 
{ 
    String starPrefix = "Text to be appended with"; 
    String replacedString = "new text has been appended"; 

    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw"); 

    String line = ""; 
    while((line = file.readLine()) != null) 
    { 
     if(line.startsWith(starPrefix)) 
     { 
      file.seek(file.getFilePointer() - RECORD_LENGTH - 1); 
      file.writeBytes(replacedString); 
     } 

    } 
} 

public static void createFile() throws IOException 
{ 
    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw"); 

    String line1 = "one two three"; 
    String line2 = "Text to be appended with"; 
    String line3 = "five six seven"; 
    String line4 = "eight nine ten"; 

    file.writeBytes(paddingRight(line1)); 
    file.writeBytes(CRLF); 
    file.writeBytes(paddingRight(line2)); 
    file.writeBytes(CRLF); 
    file.writeBytes(paddingRight(line3)); 
    file.writeBytes(CRLF); 
    file.writeBytes(paddingRight(line4)); 
    file.writeBytes(CRLF); 

    file.close(); 

    System.out.println(String.format("File is created in [%s]", PATHNAME)); 
} 

public static String paddingRight(String source) 
{ 
    StringBuilder result = new StringBuilder(100); 
    if(source != null) 
    { 
     result.append(source); 
     for (int i = 0; i < RECORD_LENGTH - source.length(); i++) 
     { 
      result.append(EMPTY_STRING); 
     } 
    } 

    return result.toString(); 
} 

}

0

あなたは "名前を付けて保存" をクリックし、* .javaファイルの拡張子を保存するに保存することにより、Javaへtxtファイルを変更することができます。

関連する問題