无法使用renameTo()移动文件

时间:2015-12-17 10:44:32

标签: java xml file schema

我目前有一个文件监视器,它读取XML文件并根据内容更新数据库表。读取文件时,将根据特定模式对其进行验证,以确保内容正确无误。

验证结果影响文件的目标移动。

如果架构成功,将文件移动到已处理目录时没有问题,但是,当架构失败时,我无法重命名文件本身。

但是,当我调试并浏览文件路径以确保将文件移动到正确的位置时,它通常允许我重命名该文件,这使我认为这是一个计时问题。

文件监控类:

// 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文档的解析,并根据结果返回true或false值。

失败的区域位于方法的开头:

 // 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);

因为这是我们尝试重命名的文件,我认为如果验证失败,可能会使文件保持打开状态并解释为什么在通过验证时没有问题。

修改

这是验证失败的catch子句:

 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;

}

1 个答案:

答案 0 :(得分:1)

如果您想稍后重命名该文件,则必须首先关闭。显然,您的代码不会这样做。

Closing StreamSourceMoving files after failed validation (Java)建议不要传递File,而是传递FileInputStream,然后您可以自己关闭(或使用try-with-resource )

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