我目前有一个文件监视器,它读取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;
}
答案 0 :(得分:1)
如果您想稍后重命名该文件,则必须首先关闭。显然,您的代码不会这样做。
Closing StreamSource和Moving files after failed validation (Java)建议不要传递File
,而是传递FileInputStream
,然后您可以自己关闭(或使用try-with-resource )
try(InputStream in = new FileInputStream (file)) {
Source xmlFile = new StreamSource(fr);
validator.validate(xmlFile);
}