【问题标题】:Java program can't use file write after it's writtenJava程序在写入后不能使用文件写入
【发布时间】:2017-09-29 12:05:30
【问题描述】:

事情是这样的,我正在创建一个 XML 资源在创建后使用的文件。程序执行完毕后,应删除该文件。这就是发生的事情:

我运行程序,文件还不存在... 文件应该使用 FileWriter 创建:

File file = new File("src/main/resources/org/avalin/optaplanner/solver/employeeShiftsScoreRules.drl");
try (FileWriter fileWriter = new FileWriter(file))
{
    fileWriter.write("Content...");
    fileWriter.flush();
    fileWriter.close();
}
catch(IOException e)
{
        e.printStackTrace();
}

然后我有这个代码:

private static synchronized Solver buildSolver()
{
    SolverFactory solverFactory = 
    SolverFactory.createFromXmlResource(SOLVER_CONFIG_XML);
    return solverFactory.buildSolver();
}

文件写入也包含在同步方法中,但我假设由于它们没有直接访问同一个变量,因此它们没有任何效果。正在从上面看到的 SOLVER_CONFIG_XML 读取文件。

当程序结束时,它会删除给定路径上的文件,以便下次运行时根据给定程序的参数创建它。


现在这就是发生的事情...... 第一次运行程序时,我得到一个错误,说文件没有被写入。

线程“main”java.lang.IllegalArgumentException 中的异常:scoreDrl (org/avalin/optaplanner/solver/employeeShiftsScoreRules.drl) 在类加载器中不作为类路径资源存在

我可以在文件写入后立即进行打印,这结束了该方法第一次运行的结论,但由于某种原因,在程序第一次结束执行之前,文件并没有被“创建”...

第二次,程序运行良好,因为文件是在异常之前创建的?

有没有办法在我的程序的下一部分执行之前确保文件“完全写入”?该文件每次的长度都不同,因为它是根据用户输入的内容动态创建的,所以我无法检查。我会假设它会完全写入,因为它确实执行了我在 fileWriter.close() 之后所做的打印,但显然不是这样。

【问题讨论】:

  • 看起来类加载器在启动时缓存了可用文件。您需要使该缓存无效,或者可能使用自定义类加载器。

标签: java file synchronization writing


【解决方案1】:

看起来您正在将文件写入 src/main/resources 文件夹,这是 资源源 的标准位置 - 也就是说,您的构建系统从哪里读取文件,而不是从哪里读取文件你正在运行的程序可以。

虽然可以将源文件夹添加到运行问题的类路径中,但这是不好的做法 - 尝试找出构建系统将其输出写入的位置(可能是类文件和复制资源的单独文件夹)并编写你的文件。

【讨论】:

  • 您是否建议我将其写入java文件夹,然后将其复制到资源中?那会有什么不同吗?
  • 可以这样做(但将其移动到资源文件夹而不是复制到那里),但这仍然是对源文件夹的不当使用 - 在某些情况下如果这些文件夹受到保护,则可能会出现问题。将输出文件夹作为系统属性/环境变量传递如何,以便您可以从外部控制它?
猜你喜欢
  • 1970-01-01
  • 2016-09-15
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多