2015-12-17 2 views
1

В настоящее время у меня есть файловый монитор, который читает XML-файл и обновляет базу данных базы данных на основе содержимого. Когда файл читается, он проверяется на соответствие конкретной схеме, чтобы обеспечить правильность содержимого.Невозможно переместить файл с помощью renameTo()

Результат проверки влияет на предназначение файла для перемещения.

Если схема прошла успешно, при перемещении файла в обработанный каталог проблем не возникает, однако при сбое схемы я не могу переименовать сам файл.

Однако, когда я отлаживаю и исследую пути к файлу, чтобы гарантировать, что файл перемещается в нужное место, он часто позволяет мне переименовать файл, что заставляет меня думать, что это проблема синхронизации.

File Monitor Класс:

// Get a directory listing; 
FilterFiles filterFiles = new FilterFiles(); 
String inbox = GlobalVars.getConfiguration().getInboundInbox(); 
String [] dir = new File(inbox).list(filterFiles); 

// Wait 500 ms before obtaining files (Avoid the ResourceBusy error);  
    try { 
     Thread.sleep(500); 
    } catch (InterruptedException e) { 

     // Log errors 
     logger.info("Interrupted Exception " + e.getMessage()); 
     new LogStackTrace(logger, e); 

     e.printStackTrace(); 
    } 

    // Iterate through directory; 
    for (int a=0; a < dir.length; a++) { 

     // Derive the full file path i.e. folder + path name; 
     String fullFilePath = GetAbsoloutePath.getFullAbsoluteFilePath(inbox, dir[a]); 

     logger.info("=========================================================="); 
     logger.info(""); 
     logger.info("Found File : " + fullFilePath); 
     logger.info("=========================================================="); 

     // Does the file exist & can we read the file at this time; 
     File file = new File(fullFilePath); 

     if (file.exists() && file.canRead()) { 

      // Process the file; 
      StringBuffer renamedFile = new StringBuffer(); 

      // Rename the file to indicate InProgess; 
      String fileName = file.getAbsolutePath(); 
      String fileNameInProgress = fileName.trim() + ".InProgress"; 

      // Delete the file if exists where we are moving the file to; 
      File deleteFile = new File(fileNameInProgress); 

      if (deleteFile.delete()) logger.info("Existing file deleted: " + fileNameInProgress); 

      // Ensure file is renamed so we can see it is in progress 
      if (!file.renameTo(new File(fileNameInProgress))) { 

       // Logging 
       logger.error("Failed to renamed file :" + fileName + " to " + fileNameInProgress); 
       break; 
      }else{ 

       logger.info("Renamed file to : " + fileNameInProgress); 

       // Pass back name of renamed file; 
       renamedFile.append(fileNameInProgress); 

       File renamedFileRef = new File(renamedFile.toString()); 

       // Path to move - could be errors or processed 
       String pathToMove = ""; 

       // Parse XMobject 
       ParseInboundXML par = new ParseInboundXML(); 

       // check if parse was succesful 
       if(par.parseXML(renamedFileRef, con)){ 

        // Path to move XML file 
        pathToMove = GlobalVars.getConfiguration().getInboundProcessed()+ "\\" + file.getName(); 

        //Logging 
        logger.info("File parsed and tables updated successfully"); 
        logger.info("Moving file to : " + pathToMove); 
       }else{ 

        pathToMove = GlobalVars.getConfiguration().getInboundErrors()+ "\\" + file.getName(); 

        //Logging 
        logger.error("Errors when parsing file and updating tables"); 
           logger.error("Moving file to : " + pathToMove); 
       } 


     // Help with garbage collection 
     par = null; 

     // New file 
     File newPath = new File(pathToMove); 

     // Need to check if this already exists in processed- if so we must override the existing file 
     // Otherwise the move will not be processed and the same docuemnt will be continously processed 
     if(newPath.exists()) 
       newPath.delete(); 

После того, как приведенный выше код был выполнен, этот блок кода выполняется, и это то, где переименования не удается:

 // Rename path so it is placed in processed folder 
      if(renamedFileRef.renameTo(newPath)){ 

        //Logging 
        logger.info("File processed successfully"); 
      }else{ 

        // Logging 
        logger.error("Unable process file"); 
      } 

В коде вы можете заметить звоните по адресу:

// Parse XMobject 
ParseInboundXML par = new ParseInboundXML(); 

// check if parse was succesful 
if(par.parseXML(renamedFileRef, con)){ 

Этот метод является методом проверки и анализа синтаксического анализа XML-документ и возвращает истинное или ложное значение в зависимости от результата.

Область, в которой он не находится в начале метода:

// Find schema path 
String schemaPath = GlobalVars.getConfiguration().getInboundSchemaLocation(); 
String schemaFileName = "WMS_" + file.getAbsoluteFile().toString().split("#")[2] + ".xsd"; 

// Schema location 
String schemaLocation = schemaPath + "\\" + schemaFileName; 

// Create schema factory 
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 

// Schema file 
Source schemaFile = new StreamSource(new File(schemaLocation)); 

// Apply schema and validate XML 
Schema schema = schemaFactory.newSchema(schemaFile); 
Validator validator = schema.newValidator(); 
Source xmlFile = new StreamSource(file); 
validator.validate(xmlFile); 

Я думаю, что этот вопрос может лежать вокруг

Source xmlFile = new StreamSource(file); 

, как это файл мы пытаемся переименовать, и я думаю, что если он не прошел проверку, возможно, что это может держать файл открытым и объясняет, почему нет проблем при его проверке.

EDIT

Это положение задвижки для неудачной проверки:

catch (SAXException e) { 

     // Write Error Record 
     CreateErrorMessages.createIW702Message(record.getTrno701TransactionNumber(), IntegrationConstants.SAX_ERROR, "SAX Error", e.toString(), con); 

     // Logging 
     logger.info("SAX Exception " + e.getMessage()); 

     // Log stack trace 
     new LogStackTrace(logger, e); 

     // Prints to stack trace 
     e.printStackTrace(); 

     return false; 

} 
+0

Вы убедились, что файл/xmlSource правильно закрыт в случае исключений? Я не вижу обработки исключений или try-with-resource в вашем коде. – Jan

+0

Сам файл является тем, который я пытаюсь переименовать, поэтому я не хочу его закрывать. Объект Source для xmlSource не имеет ничего, что позволило бы мне закрыть это: https: // docs .oracle.com/JavaSE/7/документы/API/javax/XML/преобразования/Source.html – Nathan

+0

Также я упустил попытку catch, потому что я не хотел, чтобы вопрос был слишком большим, но я приведу пример одного из них, который улавливает исключения, вызванные вызовом метода validation(), - см. мое редактирование для пример предложения catch, который в настоящее время используется для неудачных проверок – Nathan

ответ

1

Если вы хотите, чтобы позже переименовать файл, он должен быть закрыт первого. По-видимому, ваш код этого не делает.

Closing StreamSource и Moving files after failed validation (Java) предлагают не переходить в File но вместо FileInputStream, что вы можете затем закрыть в конце самостоятельно (или использовать примерочных с-ресурса)

try(InputStream in = new FileInputStream (file)) { 
    Source xmlFile = new StreamSource(fr); 
    validator.validate(xmlFile); 
} 
+0

Фантастично, что сработало отлично - я предполагаю, что если файл прошел проверку, то validator.validate (xmlFile) должен посмотреть, чтобы закрыть поток, но если проверка не удалась, должен держать поток открытым, блокируя файл в процессе. Спасибо за помощь. – Nathan

Смежные вопросы