Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java验证程序在失败时锁定文件-我做错了什么?_Java_Xml_Validation - Fatal编程技术网

Java验证程序在失败时锁定文件-我做错了什么?

Java验证程序在失败时锁定文件-我做错了什么?,java,xml,validation,Java,Xml,Validation,我试图根据Java中的模式验证XML文件,问题是如果文件验证失败,那么文件将被锁定,直到应用程序终止。如果输入文件有效,则文件不会被锁定,一切正常 我正在使用javax.xml.validation.Validator和validate()方法。这看起来很简单,当验证通过时就可以了。我只能假设我在错误处理中遗漏了一些东西,但是Validator的API似乎没有提供任何有用的东西。谁能解释一下我做错了什么 我已经将所有这些简化为下面的一个独立类。如果在扫描仪启动时运行此操作,请检查输入文件,您可以

我试图根据Java中的模式验证XML文件,问题是如果文件验证失败,那么文件将被锁定,直到应用程序终止。如果输入文件有效,则文件不会被锁定,一切正常

我正在使用
javax.xml.validation.Validator
validate()
方法。这看起来很简单,当验证通过时就可以了。我只能假设我在错误处理中遗漏了一些东西,但是Validator的API似乎没有提供任何有用的东西。谁能解释一下我做错了什么

我已经将所有这些简化为下面的一个独立类。如果在扫描仪启动时运行此操作,请检查输入文件,您可以看到它现在已锁定。我可以提供一个输入和结构文件,如果你需要它

谢谢

菲尔

更新:


我有一点黑客,它提供了一个(糟糕的)解决方案。我向schemaValidator添加了一个自定义错误处理程序。此errorHandler只在成员变量中存储任何错误。这意味着验证器将始终成功,从而释放输入文件上的所有锁。但是,我必须检查错误处理程序,看看是否有错误,如果有,则抛出一个错误。这不是很好,但确实解决了这个问题。

捕获validate()调用中引发的异常,关闭链接到文件的StreamSource对象以释放文件资源,然后将异常抛出到调用方法


编辑:您可能需要显式检索InputStream以关闭底层文件句柄-StreamSource似乎没有定义一种显式方式来关闭底层流。检查是否获得source.getInputStream()返回的InputStream对象-如果是,关闭该对象将释放文件的所有底层句柄。

注意,不允许使用StreamSource实例。 ()


验证程序无法关闭
。这可能是唯一的原因(但可能还有其他原因,因此您可能需要重新考虑您的方法。)

应用程序将需要负责关闭流。为了确保发生这种情况,可以使用
finally

public static void validate(URI xmlLocation, URI schemaLocation) 
  throws Exception 
{
  SchemaFactory schemaFactory = 
    SchemaFactory.newInstance( "http://www.w3.org/2001/XMLSchema" );
  InputStream sIn = schemaLocation.toURL().openStream();
  try {
    Source schemaSource = new StreamSource(sIn, schemaLocation.toString());
    Schema schema = schemaFactory.newSchema(schemaSource);
    Validator schemaValidator = schema.newValidator();
    InputStream xIn = xmlLocation.toURL().openStream();
    try {
      StreamSource source = new StreamSource(xIn, xmlLocation.toString());
      schemaValidator.validate( source );
    } finally {
      xIn.close();
    }
  } finally {
    sIn.close();
  }
}

要么是因为OP错误地使用了这些类。我个人没有使用过StreamSources,因此没有进一步的建议提供-但锁定的文件等同于未发布的文件句柄,我在上面看到的唯一候选对象是StreamSource对象。它似乎是一个bug。。。如果文件验证失败,则文件将被锁定,直到应用程序终止。如果输入文件有效,则文件不会被锁定,一切正常。“.IMHO文件应始终独立于结果锁定或释放。如果我错了,请更正我的想法StreamSource的inputStream为空。是的,StreamSource没有有用的“关闭”“我完全同意你的看法。”!我只是对这种行为感到惊讶。顺便说一句,我已经在JDK1.6和1.7上试过了。我更愿意相信这是我糟糕的编码,而不是一个bug。好吧,验证会根据接口引发IO或SAX异常,这两个异常都不是在进行验证的方法中处理的——因此我认为这很可能与不清理方法中创建的源有关。编辑:@Phil-好吧,奇怪。尝试getReader()并查看是否返回任何内容?您使用的是什么XML API提供程序?在最新的JDK中没有这样的限制,但仍然存在此错误。您必须实例化FileInputStream并在异常处理程序中关闭它:(我也遇到过这个问题(主要是在windows LOL上),我认为这是一个JDK错误。。。
URL xmlFileURL = xmlFileToCheck.toURI().toURL();
InputStream inputStream = xmlFileURL.openStream();
InputSource is = new InputSource(inputStream);
SAXSource saxSource = new SAXSource(is);

xmlValidator.validate(saxSource);

inputStream.close(); // this is probably important...
public static void validate(URI xmlLocation, URI schemaLocation) 
  throws Exception 
{
  SchemaFactory schemaFactory = 
    SchemaFactory.newInstance( "http://www.w3.org/2001/XMLSchema" );
  InputStream sIn = schemaLocation.toURL().openStream();
  try {
    Source schemaSource = new StreamSource(sIn, schemaLocation.toString());
    Schema schema = schemaFactory.newSchema(schemaSource);
    Validator schemaValidator = schema.newValidator();
    InputStream xIn = xmlLocation.toURL().openStream();
    try {
      StreamSource source = new StreamSource(xIn, xmlLocation.toString());
      schemaValidator.validate( source );
    } finally {
      xIn.close();
    }
  } finally {
    sIn.close();
  }
}