2016-07-25 1 views
-1

私はcsvファイルのフォーマットはid,textです。次に例を示します。See you laterJavaでは、ファイル内の行の特定の部分をどのように上書きするのですか?

に、

helloText,How are you 
goodbyeMessage,Some new text for a change 
errorMessage,Oops something went wrong 

は、今私はSome new text for changeあるgoodbyeMessageのテキスト部分を編集したいたとえば言うことができますcsvの結果は、このようになります。

helloText,How are you 
goodbyeMessage,See you later 
errorMessage,Oops something went wrong 

私はファイルに書き込むことができるコードを持っていますが、コードの実行が終了すると、これはcsvファイルになります:

helloText,How are you 
goodbyeMessage,Some new text for a change 
errorMessage,Oops something went wronggoodbyeMessage,See you later 

FileWriterのappendの値をtrueに設定しているため、これが発生していることがわかりました。もし私がすべてを拭くのではない。

私はFileWriter.newLine()を使って試してみましたが、それはより良く見えるようにしましたが、これは私が達成しようとしているものではありません。私はまだファイルに同じ数の行が必要です。 MyApp.java

public static void main(String[] args) throws FileNotFoundException, IOException { 
    PropsWriter pw = new PropsWriter("test_props.txt"); 
    pw.updateElementText("goodbyeMessage", "See you later"); 
} 

PropsWriter.java

/** 
* Updates the text of a given element in the properties file. 
* 
* @param id The id of the element 
* @param newText The text that will replace the original text. 
* 
* @throws IOException If I/O error occurs 
*/ 
public void updateElementText(String id, String newText) throws IOException { 
    Assertions.checkNotNull(id, "Id must not be null."); 
    Assertions.checkNotNull(id, "Id must not be an empty string."); 
    File file = new File(pathName); 
    BufferedReader br = new BufferedReader(new FileReader(file)); 
    BufferedWriter wr = new BufferedWriter(new FileWriter(file, true)); 
    try { 
     String line; 

     while((line = br.readLine()) != null) { 
      if(line.contains(id)) { 
       //returns true 
       System.out.println("Is line there: " + line.contains(id)); 

       //returns helloText 
       System.out.println("ID: " + extractId(line)); 

       //returns How are you 
       System.out.println("TEXT: " + extractText(line)); 

       //returns Some new text for a change 
       System.out.println("NEW_TEXT: " + newText); 

       // This is where I am trying to replace the old text 
       // with new text that came from the main method. 
       line = line.replaceAll(extractText(line), newText); 
       //wr.newLine(); 
       wr.write(line);    
      } 
     } 
    } catch(IOException e) { 
     e.printStackTrace(); 
    } finally { 
     wr.close(); 
    } 
} 

/** 
* Gets the id part of a line that is stored in the 
* properties file. 
* 
* @param element The element the id is got from. 
* @return String representation of the id. 
*/ 
private static String extractId(String line) { 
    final int commaOccurence = getFirstCommaOccurrence(line); 
    return line.substring(0, commaOccurence); 
} 

/** 
* Gets the text part of a line that is stored in the 
* properties file. 
* 
* @param element The element the text is got from. 
* @return String representation of the text. 
*/ 
private static String extractText(String line) { 
    final int commaOccurence = getFirstCommaOccurrence(line); 
    return line.substring(commaOccurence + 1, line.length()); 
} 

/** 
* Gets the first occurrence of a comma in any given line of a text file. 
* @param element 
* @return 
*/ 
private static int getFirstCommaOccurrence(String line) { 
    return line.indexOf(","); 
} 
+2

あなたはただそれを言った。 'FileWriter'を' true'に設定しないでください(新しいものだけが追加されるため)。ファイル全体を読み込み、全ての行を保存する必要があります(例えば 'List ')。次に、データを操作します。その後、**完全**テキストを書き換えます(例えば、上記の 'List 'を使用して)。しかし、どのラインを追加する必要があるかを正確に知っていれば(そしてその場所を見つける必要はありません)、もっと低レベルのFile-Writerがあなたのためにもっと良いかもしれません。 – Zabuza

+0

ファイルに何千もの行が含まれている場合、同じことをしますか? – cod3min3

+0

行を検索する必要がある場合は、すべての行を繰り返し処理する必要があります。すべての行を保存する必要はありません(ファイルが大きい場合)。正確な場所を覚えて、より低レベルのFile-Writerを使用することもできます。たとえば、 'RandomAccessFile'の場合:https://examples.javacodegeeks.com/core-java/io/randomaccessfile/java-randomaccessfile-example – Zabuza

答えて

0

は残念ながら、実際にいくつかの変更可能なオブジェクトにすべてのファイルのデータをロードする以外に(私の知っていること)これを行う方法はありませんそれをすべてファイルに書き戻します。

Filesクラスは@Zabuzaコメントで述べたように、Java(登録商標)は、A内の特定の場所に移動することができRandomAccessFileと呼ばれるクラスを提供List


にファイル全体を読み取るための便利な方法を提供ファイルを作成し、バイトを上書きします。あなたが興味を持つかもしれ 方法には次のようになります。

希望すると便利です。

+0

'RandomAccessFile'はhttps://examples.javacodegeeksの前(ただし後)のものを変更しないことで、正確な位置に読み込むことができます。COM /コア-javaの/ IO /のRandomAccessFile/javaの-例-のRandomAccessFile – Zabuza

1

あなたはちょうどそれを言った。 FileWritertrueに設定しないでください(にはの新しいものが追加されます)。ファイル全体を読み込み、すべての行を保存する必要があります(たとえば、List<String>)。次に、データを操作します。その後、テキスト全体を書き換えます(例えば、上記のList<String>を使用して)。他の行は、その後迷子と同じように

BufferedWriter wr = new BufferedWriter(new FileWriter(file, false)); 

第二は、常に、ファイルへの書き込み:あなたの上記のコードで

これはが最初truefalseで置き換えるだろう

if(line.contains(id)) { 
    ... 
    line = line.replaceAll(extractText(line), newText); 
} 
wr.write(line); 

しかし、非常に大きなファイルがあり、すべてを行書き換えたくない場合は、 RandomAccessFileのように、より低いレベルのFileWriterに行くことができます。このコンセプトでは、この位置より前のすべてを書き換えずに、指定された位置でファイル操作を開始することができます。あなたは、行を検索することができます(またはどこか分かっていればジャンプしてください)。しかし、の後にとなるすべてのものを書き換える必要があります。使用例を次に示します。RandomAccessFile example

これはプラットフォームに依存するため、これ以上の解決策はありません。具体的には、使用するファイルシステムに依存します(例:NTFSまたはFAT32など)。
一般に、ファイルを複数のパッケージに分割して格納します。パッケージは、ハードドライブ全体に保存され、最適な場所に配置されます。ファイルシステムは、ファイルの各開始パッケージへのポインタをmaster tableに保存します。次に、すべてのパッケージはEOFに達するまで次のパッケージへのポインタを保存します。

これまでのことをすべて変更することなく、途中で何かを変更するのは簡単です。しかし、OSが新しいデータをパッケージに分割する方法を制御することはできないので、おそらく後に続くものを変更する必要があります。 非常に低いレベルに行くと、後ですべてを変更することなく、単一のパッケージを制御してデータを注入することができます。しかし、私はあなたがこれをしたいとは思わない:)

関連する問題