2017-12-11 4 views
0

파일 트리를 거쳐 루트가없는 XML 파일에 루트를 추가하는 코드가 있습니다. 내 문제는 inputstream에서 출력 스트림으로 쓰려고 할 때입니다. 현재 XML 파일을 업데이트 된 버전 (루트가 추가 된 버전)으로 바꾸고 싶습니다. outputstream을 inputstream과 동일한 파일로 만들면 문제가 발생한다고 생각합니다. 직관적으로 그것은 그것이 문제가 될 것이라는 것을 이해하는 것처럼 보입니다. 그렇지 않다면 알려주세요.Java inputstream/outputstream 같은 이름의 파일에 쓰기

어떻게 해결할 수 있습니까? 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

관련 문제