Java 7 WatchService - 该进程无法访问该文件,因为它正被另一个进程使用

标签 java file-io java-7 watchservice

我关注了 Watching a Directory更改 Java7 nio2 教程以使用代码示例 WatchDir.java 递归监视目录的全部内容。

代码如下:

// Get list of events for the watch key.
for (WatchEvent<?> event : key.pollEvents()) {
// This key is registered only for ENTRY_CREATE events, but an OVERFLOW event 
// can occur regardless if events are lost or discarded.
if (event.kind() == OVERFLOW) {
    continue;
}

// Context for directory entry event is the file name of entry.
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path fileName = ev.context();
Path fullPath = dir.resolve(fileName);

try {
    // Print out event.
    System.out.print("Processing file: " + fileName);

    processed = fileProcessor.processFile(fullPath);

    System.out.println("Processed = " + processed);

    if (processed) {
        // Print out event.
        System.out.println(" - Done!");
    }
} 
catch (FileNotFoundException e) {
    System.err.println("Error message: " + e.getMessage());
}
catch (IOException e) {
    System.err.println("Error processing file: " + fileName.toString());
    System.err.println("Error message: " + e.getMessage());
}

好的,所以问题(我确定做了一些愚蠢的事情)就在这里:

processed = fileProcessor.processFile(fullPath);

它的作用是这样的:

public synchronized boolean processFile(Path fullPath) throws IOException {
String line;
String[] tokens;
String fileName = fullPath.getFileName().toString();
String fullPathFileName = fullPath.toString();

// Create the file.
File sourceFile = new File(fullPath.toString());

// If the file does not exist, print out an error message and return.
if (sourceFile.exists() == false) {
    System.err.println("ERROR: " + fullPathFileName + ": No such file");
    return false;
}

// Check file extension.
if (!getFileExtension(fullPathFileName).equalsIgnoreCase("dat")) {
    System.out.println(" - Ignored.");
    return false;
}

// Process source file.
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) {
    int type;

    // Process each line of the file.
    while (bReader.ready()) {

        // Get a single line.
        line = bReader.readLine();

        // Get line tokens.
        tokens = line.split(delimiter);

        // Get type.
        type = Integer.parseInt(tokens[0]);

        switch (type) {
        // Type 1 = Salesman.
        case 1:
            -> Call static method to process tokes.
            break;
        // Type 2 = Customer.
        case 2:
            -> Call static method to process tokes.
            break;
        // Type 3 = Sales.
        case 3:
            -> Call static method to process tokes.
            break;
        // Other types are unknown!
        default:
            System.err.println("Unknown type: " + type);
            break;
        }
    }

    PrintStream ps = null;
    try {

        // Write output file.
        // Doesn't matter. 

    } 
    finally {               
        if (ps != null) {
            ps.close();
        }
    }
    return true;
}
}

我第一次处理事件时,一切正常!即使有超过 1 个文件要处理。但是在连续的时间里,我收到这个错误信息:

The process cannot access the file because it is being used by another process

我在这里做错了什么?我该怎么做才能成功处理连续的文件?

我忘记提及的两个重要注意事项:

  1. 我使用的是 Windows 7。
  2. 当我在 Debug模式下运行应用程序时,它可以正常工作。

编辑:如果我在尝试使用该文件之前添加 sleep ,它会起作用:

Thread.sleep(500);

// Process source file.
try (BufferedReader bReader = new BufferedReader(new FileReader(sourceFile))) {

那么,有没有可能是Windows没有及时解锁文件呢?我该如何解决(以适当的方式)?

最佳答案

好的,我找到了解决方案。我不知道这是否是最好的方法,但它确实有效。 不幸的是,file.canRead() 和 file.canWrite() 都返回 true,即使文件仍然被 Windows 锁定。所以我发现,如果我尝试用相同的名称“重命名”它,我就知道 Windows 是否正在处理它。所以这就是我所做的:

    while(!sourceFile.renameTo(sourceFile)) {
        // Cannot read from file, windows still working on it.
        Thread.sleep(10);
    }

关于Java 7 WatchService - 该进程无法访问该文件,因为它正被另一个进程使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15531144/

相关文章:

java - 在 imageview JavaFx 上显示图像

java - JPA @MappedSuperclass 子类的不同 Id 计数器

java - 使用 UriComponentsBuilder 编码查询参数

Java - 如果要发送的文件不是普通文本文件,则通过套接字发送的文件为空

c++ - 写入大文件

java - 是否可以调用绝对函数在 TYPE_FORWARD_ONLY 结果集中向前移动行?

java - 获取 java.lang.NoClassDefFoundError : org/apache/xpath/objects/XObject

python - 读取具有指定换行符的文件

java - 打开 PDF 只能在 netbeans 中使用

java - 我如何使用 JDK 1.7 运行 jersey 2.26?