2017-12-11 37 views
0

ファイルツリーを通過するコードがあり、そのファイルツリーを持たないXMLファイルにルートを追加しています。私の問題は、入力ストリームから出力ストリームに書き込もうとするときです。現在のxmlファイルを更新されたバージョン(ルートが追加されたもの)で置き換えたいと思います。出力ストリームを入力ストリームと同じファイルにすると問題が発生すると思います。直感的には、それが問題になると思うようです。そうでない場合は、私に知らせてください。Javaの入力ストリーム/出力ストリーム同じ名前のファイルに書き込む

これをどのように修正できますか? xmlファイルを本質的に「更新」すれば、実際にはもう一方を上書きできますか?私はここで他の答えを見てきましたが、遠くまでは得ていません。

private static void addRootHelper(File root){ 
    FileInputStream fis; 
    List<InputStream> streams; 
    InputStream is; 
    OutputStream os; 

    File[] directoryListing = root.listFiles(); 
    if (directoryListing != null) { 
     for (File child : directoryListing) { 
      addRootHelper(child); 
     } 
    } 
    else { 
     try{ 
      // Add root to input stream and create output stream 
      fis = new FileInputStream(root); 
      streams = Arrays.asList(new ByteArrayInputStream("<root>".getBytes()),fis, new ByteArrayInputStream("</root>".getBytes())); 
      is = new SequenceInputStream(Collections.enumeration(streams)); 
      os = new FileOutputStream(root.getAbsolutePath()); 

      // Write from is -> os 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 

      // Read from is to buffer 
      while((bytesRead = is.read(buffer)) !=-1){ 
       os.write(buffer, 0, bytesRead); 
      } 
      is.close(); 
      os.flush(); 
      os.close(); 
      System.out.println("Added root to " + root.getName()); 

     } 
     catch(IOException ex){ 
      ex.printStackTrace(); 
     } 
    } 
} 
+2

どのようにファイルから同時に読み書きできるようになると思いますか?あなたができることは、別の一時ファイルに出力を書き込むことです。元のファイルを削除し、一時ファイルの名前を元の名前に変更します。またはファイルが十分に小さい場合は、ファイル全体をメモリにロードするか、メモリ内で完全に処理し、ファイルを閉じてから書き戻します。 – slipperyseal

+0

ええ、私はそれが問題だと思った。私はあなたの解決策を考えましたが、よりエレガントな方法があるかどうか疑問に思っていました。もしそうでなければ、それは確かに動作します! – dj1121

答えて

1

一般的な一時ファイル方式を使用したくない場合は、ファイル全体を読み込んでから後で書き戻すことができます。

ここは簡単な実装です。

public static void addRootTag(File xml) throws IOException { 
    final List<String> lines = new ArrayList<>();; 
    try (Scanner in = new Scanner(xml)) { 
     while (in.hasNextLine()) 
      lines.add(in.nextLine()); 
    } 

    try (PrintStream out = new PrintStream(xml)) { 
     out.println("<root>"); 
     for (String line : lines) { 
      // indentation, if you want 
      out.print(" "); 
      out.println(line); 
     } 
     out.println("</root>"); 
    } 
} 
+0

これはすばらしい、ありがとう! – dj1121

関連する問題