سؤال

ولقد اثنين من المواضيع مستقلة F1 و F2 (على وجه الدقة، مثيلين من java.util.concurrent.FutureTask) التي تعمل في وقت واحد.

وF1 القيام ببعض المعالجة، ثم قم بنسخ النتيجة في ملف XML. ثم، فإنه يكرر هذه الخطوات حتى أنه له علاقة (يتم إنشاء العديد من الملفات XML) لا شيء. F2 تبدو في الدليل الإخراج F1، واتخاذ ملف واحد، تحليل ذلك، وتنفيذ بعض معالجة على ذلك.

وهذا يعمل بشكل جيد للغاية، إلا أن بيانات XML في بعض الأحيان، ويحصل على F2 اقتطاع من ملف. أعني أن XML غير مكتملة، حيث بعض عقدة XML هي غير موجودة. والمشكلة هي أنه ليس reproductible دائما، والملفات التي تم اقتطاعها ليست دائما هي نفسها. بسبب ذلك، وأنا أفكر أنه في حين 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، يكون الناتج F1 إلى ملف .temp، ثم تسميته إلى .xml كخطوة نهائية. بهذه الطريقة، سيكون F2 تجاهل تبذل F1 الملف حتى يتم F1 تماما معها.

نصائح أخرى

استخدم الكلمة متزامنة على القواسم المشتركة كائن، فإن الكائن ملف يشير إلى ملف يكون الأفضل في هذه الحالة:

 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