2013-03-20 10 views
6

द्वारा किया जा रहा है, मैंने कोड नमूना WatchDir.java का उपयोग कर निर्देशिका की संपूर्ण सामग्री को पुन: क्रमबद्ध करने के लिए Watching a Directory परिवर्तनों के लिए Java12 nio2 ट्यूटोरियल का पालन किया।जावा 7 वॉच सर्विस - प्रक्रिया फ़ाइल तक नहीं पहुंच सकती है क्योंकि इसका उपयोग किसी अन्य प्रक्रिया

कोड इस तरह दिखता है:

// Get list of events for the watch key. 
for (WatchEvent<?> event : key.pollEvents()) { 
// This key is registered only for ENTRY_CREATE events, but an OVERFLOW event 
// can occur regardless if events are lost or discarded. 
if (event.kind() == OVERFLOW) { 
    continue; 
} 

// Context for directory entry event is the file name of entry. 
@SuppressWarnings("unchecked") 
WatchEvent<Path> ev = (WatchEvent<Path>)event; 
Path fileName = ev.context(); 
Path fullPath = dir.resolve(fileName); 

try { 
    // Print out event. 
    System.out.print("Processing file: " + fileName); 

    processed = fileProcessor.processFile(fullPath); 

    System.out.println("Processed = " + processed); 

    if (processed) { 
     // Print out event. 
     System.out.println(" - Done!"); 
    } 
} 
catch (FileNotFoundException e) { 
    System.err.println("Error message: " + e.getMessage()); 
} 
catch (IOException e) { 
    System.err.println("Error processing file: " + fileName.toString()); 
    System.err.println("Error message: " + e.getMessage()); 
} 

ठीक है, तो समस्या (जहां मैं बेवकूफ कुछ कर रही यकीन है) यहाँ है:

processed = fileProcessor.processFile(fullPath); 

तथा उसके द्वारा कुछ इस तरह है:

public synchronized boolean processFile(Path fullPath) throws IOException { 
String line; 
String[] tokens; 
String fileName = fullPath.getFileName().toString(); 
String fullPathFileName = fullPath.toString(); 

// Create the file. 
File sourceFile = new File(fullPath.toString()); 

// If the file does not exist, print out an error message and return. 
if (sourceFile.exists() == false) { 
    System.err.println("ERROR: " + fullPathFileName + ": No such file"); 
    return false; 
} 

// Check file extension. 
if (!getFileExtension(fullPathFileName).equalsIgnoreCase("dat")) { 
    System.out.println(" - Ignored."); 
    return false; 
} 

// Process source file. 
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) { 
    int type; 

    // Process each line of the file. 
    while (bReader.ready()) { 

     // Get a single line. 
     line = bReader.readLine(); 

     // Get line tokens. 
     tokens = line.split(delimiter); 

     // Get type. 
     type = Integer.parseInt(tokens[0]); 

     switch (type) { 
     // Type 1 = Salesman. 
     case 1: 
      -> Call static method to process tokes. 
      break; 
     // Type 2 = Customer. 
     case 2: 
      -> Call static method to process tokes. 
      break; 
     // Type 3 = Sales. 
     case 3: 
      -> Call static method to process tokes. 
      break; 
     // Other types are unknown! 
     default: 
      System.err.println("Unknown type: " + type); 
      break; 
     } 
    } 

    PrintStream ps = null; 
    try { 

     // Write output file. 
     // Doesn't matter. 

    } 
    finally {    
     if (ps != null) { 
      ps.close(); 
     } 
    } 
    return true; 
} 
} 

पहली बार जब मैं किसी ईवेंट को संभालता हूं, तो यह सब ठीक काम करता है! यहां तक ​​कि अगर प्रक्रिया करने के लिए 1 से अधिक फाइलें हैं। लेकिन लगातार समय में, मैं इस त्रुटि संदेश मिलता है:

प्रक्रिया फ़ाइल क्योंकि यह अन्य प्रक्रिया द्वारा किया जा रहा है उपयोग नहीं कर सकते

क्या मैं गलत यहाँ कर रहा हूँ? सशक्त के साथ लगातार फाइलों को संसाधित करने के लिए मैं क्या कर सकता हूं?

दो महत्वपूर्ण सूचनाएं कि मैं उल्लेख करना भूल गया:

  1. मैं Windows 7.
  2. उपयोग कर रहा हूँ जब मैं डिबग मोड में आवेदन चलाने के लिए, यह काम करता है।

संपादित करें: मैं एक नींद जोड़ देते हैं तो इससे पहले कि मैं फ़ाइल का उपयोग करने का प्रयास करें, यह काम करता है:

Thread.sleep(500); 

// Process source file. 
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) { 

तो, यह विंडोज जाता है कि समय में फ़ाइलों को अनलॉक नहीं होना संभव है? मैं इसे कैसे ठीक कर सकता हूं (उचित तरीके से)?

उत्तर

14

ठीक है, मुझे एक समाधान मिला। मुझे नहीं पता कि यह करने का सबसे अच्छा तरीका है, लेकिन यह काम करता है। दुर्भाग्यवश, file.canRead() और file.canWrite() दोनों सत्य लौटते हैं, भले ही फ़ाइल अभी भी विंडोज द्वारा लॉक हो। इसलिए मैंने पाया कि यदि मैं इसे उसी नाम से "नाम बदलने" का प्रयास करता हूं, तो मुझे पता है कि विंडोज इस पर काम कर रहा है या नहीं। तो मैंने यही किया:

while(!sourceFile.renameTo(sourceFile)) { 
     // Cannot read from file, windows still working on it. 
     Thread.sleep(10); 
    } 
+0

यह चारों ओर काम करता है :) –

+1

अच्छी चाल! यह मेरी मदद की! –

1

मुझे भी इसी तरह की समस्या थी। लेकिन जब मेरी प्रतिलिपि बनाई जा रही है तो मेरी फाइल लॉक नहीं हो रही है। अगर मैं इसे बनाने के ठीक बाद इसे पढ़ने की कोशिश कर रहा था तो यह खाली था।

मुझे लगता है कि आपके मामले में कोई ज़रूरत नहीं है और आप आसानी से त्रुटि संभाल सकते हैं और यदि आपको नींद निष्पादित करने से पहले त्रुटि मिलती है और उसके बाद पुनः प्रयास करें। लेकिन मेरे लिए यह मेरे लिए सही नहीं है। मुझे त्रुटि नहीं मिली तो मैंने आपके soloution की कोशिश की और मुझे समझ में आया कि यह मेरे लिए भी स्वीकार्य नहीं है क्योंकि मुझे पढ़ने के अलावा अधिकार नहीं हैं। तो मैं अपने 'चाल' का सुझाव दे सकता हूं। मैं कक्षा java.io.RandomAccessFile उपयोग कर रहा हूँ:

List<String> lines = null; 

while(true){ 
    try(RandomAccessFile raf = new RandomAccessFile(fileFullPath.toFile() , "r")){ 
     lines = Files.readAllLines(fileFullPath , Charset.forName(ENCODING)); 
     break; 
    }catch(FileNotFoundException ex){ 
     LOG.warn("File isn't yet completed: {}",ex.getMessage()); 
     LOG.info("Waiting {} for next attempt to read it" , SLEEP_INTERVAL_READING); 
     try { 
      Thread.sleep(SLEEP_INTERVAL_READING); 
     } catch (InterruptedException e) { 
      LOG.error("Waiting was interrupted",e); 
     } 
    }catch(Exception ex){ 
     LOG.error("Error in reading file ",ex); 
     clear(); 
     return false; 
    } 
} 
0

जब घटना प्रकार का है ENTRY_MODIFY वर्तमान धागा कुछ सेकंड के लिए सोने के लिए समय दें। मैं बिल्कुल नहीं बता सकता कि यह क्यों हो रहा है लेकिन कुछ समय में कई लॉग ENTRY_MODIFY ईवेंट मेरे लॉग में प्रिंट कर रहा है। अपने फ़ाइल आकार पर निर्भर करें कृपया नींद का समय निर्धारित करें।

if(kind == StandardWatchEventKinds.ENTRY_MODIFY){ 
try { 
    Thread.sleep(1000); 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 
//toDo - something 
} 
संबंधित मुद्दे

 संबंधित मुद्दे