문제

두 개의 독립 스레드 F1과 F2 (정확한 경우, Java.util.concurrent.futuretask의 두 인스턴스)가 병렬로 실행됩니다.

F1은 처리를 수행 한 다음 결과를 XML 파일로 복사합니다. 그런 다음 할 일이 없을 때까지 이러한 단계를 반복합니다 (많은 XML 파일이 생성됨). F2는 F1 출력 디렉토리를보고 하나의 파일을 가져 와서 구문 분석하고 일부 처리를 실행합니다.

때때로 F2가 파일에서 잘린 XML 데이터를 얻는다는 점을 제외하고는 매우 잘 작동합니다. 일부 XML 노드가 존재하지 않는 불완전한 XML을 의미합니다. 문제는 항상 재현 가능하지는 않으며 잘린 파일이 항상 동일하지 않다는 것입니다. 그로 인해 F1이 디스크에 하나의 파일을 작성하는 동안 F2가 같은 파일을 읽으려고한다고 생각합니다. 그래서 때때로 나는 이런 종류의 오류를 얻는 이유입니다.

내 질문: 파일 F1이 디스크에 쓰기로 완전히 완료 될 때까지 파일이 현재 작성되고있는 메커니즘이 있는지 궁금합니다. 따라서 파일이 잠금 해제 될 때까지 F2가 읽을 수 없습니다. 또는 내 문제를 해결하는 다른 방법은 환영받을 것입니다!

F1은 파일을 이런 식으로 작성합니다.

try {
    file = new File("some-file.xml");
    FileUtils.writeStringToFile(file, xmlDataAsString);
} catch (IOException ioe) {
    LOGGER.error("Error occurred while storing the XML in a file.", ioe);
}

F2는 파일을 이런 식으로 읽고 있습니다.

private File getNextFileToMap() {
    File path = getPath(); // Returns the directory where F1 stores the results...
    File[] files = path.listFiles(new FilenameFilter() {
        public boolean accept(File file, String name) {
            return name.toLowerCase().endsWith(".xml");
        }
    });
    if (files.length > 0) {
        return files[0];
    }
    return null;
}

// Somewhere in my main method of F2
...
f = getNextFileToMap();
Node xmlNode = null;
try {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(f);
    if (doc != null) {
        xmlNode = doc.getDocumentElement();
    }
} catch (Exception e) {
    LOGGER.error("Error while getting the XML from the file " + f.getAbsolutePath(), e);
}
도움이 되었습니까?

해결책

이미 필터링하고 있기 때문에 .xml F2의 파일은 a에 f1 출력이 있습니다 .temp 파일, 이름을 바꿉니다 .xml 마지막 단계로. 이렇게하면 F2가 F1이 완전히 완료 될 때까지 F1 파일을 무시합니다.

다른 팁

당신은 java.nio.channels.FileLock API?

더 간단한 솔루션은 다른 파일 이름 (예 : foo.tmp)에 작성한 다음 준비가되면 이름을 바꾸는 것일 수 있습니다. 다른 프로세스에서는 XML 파일이 완료되어야합니다. 이것은 잠금보다 훨씬 간단 할 것입니다.

키워드를 사용하십시오 동기화 공통 객체에서는 파일을 가리키는 파일 객체 가이 경우에 가장 좋습니다.

 class MyFileFactory {
     private static HashMap<string,File> files = new HashMap<String,File>();
     public static File get(String name) {
         if (!files.keyExists(name)) {
              files.put(name, new File(name));
         }
         return files.get(name);
     }
 }

 // Another class
 synchronized(File f = MyFileFactory::get("some-file.xml")) {
      // read or write here
 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top