java - 面对多线程堆栈跟踪 - 该进程无法访问该文件,因为它正被另一个进程使用

标签 java multithreading

我正面临尝试监视目录(使用 Java 7 Watcher 服务)并将任何新文件通过 FTP 传输到另一台机器的问题。

我让它运行并且“有时”正常运行,但看起来我遇到了线程问题。我的观察者服务似乎保留了一个文件,我正试图通过另一个线程获取该文件的内容。我尝试使用 Process Explorer,但找不到原始进程。

如果您愿意,我可以(再次)粘贴下面的代码。任何人都知道如何调试我面临的这个问题

编辑。这是代码:

public class WatchDir implements Runnable{

...
...
   void processEvents() {

        for (;;) {

            // wait for key to be signalled
            WatchKey key;
            try {
                key = watcher.take();
            } catch (InterruptedException x) {
                return;
            }

            Path dir = keys.get(key);
            if (dir == null) {
                System.err.println("WatchKey not recognized!!");
                continue;
            }

            for (WatchEvent<?> event: key.pollEvents()) {
                WatchEvent.Kind kind = event.kind();

                // Context for directory entry event is the file name of entry
                WatchEvent<Path> ev = cast(event);
                Path name = ev.context();
                Path child = dir.resolve(name);

                if(!Files.isDirectory(child, NOFOLLOW_LINKS)){
                    //Callable<LftFile> worker;

                    try {
                        this.file = new LftFile(child.toFile(), kind != ENTRY_CREATE);  <-- RIGHT HERE
                        // ADD TO FTP method
                    } catch ...
...
...


LftFile's method that causes issue:

    public long getfileHash(File f) {
        long crc = -1;
        try ( InputStream in = new FileInputStream(f) ) {   <-- This FIS is causing it
            CRC32 crcMaker = new CRC32();
            byte[] buffer = new byte[2048];
            int bytesRead;
            while((bytesRead = in.read(buffer)) != -1) {
                crcMaker.update(buffer, 0, bytesRead);
            }
            crc = crcMaker.getValue();  
        } catch (FileNotFoundException fnf) {
            logger.error("File Not Found {}", fnf);

        } catch (IOException ioe) {
            logger.error("File IOException {}", ioe);

        } catch (Exception e) {
            logger.error("File IOException {}", e);
        }       
        return crc;
    }

最佳答案

你遇到的问题是你不能让两个进程同时打开同一个文件;一个进程是将新文件添加(和写入)到您的目录,另一个进程(您的程序)试图打开它以读取它并从中计算哈希值。

您可以做的最好的事情是捕获异常并在文件可以由您的程序独占打开几秒钟后重试。

更新

看看你的代码,我认为添加试错方法很简单,只需在你的代码中做这样的事情:

boolean sucess = false;
while(!success) {
    try {
        this.file = new LftFile(child.toFile(), kind != ENTRY_CREATE);
        sucess = true;
        // ADD TO FTP method
    } catch (IOException e) { // or a more explicit exception rather than a generic IOException
        Thread.sleep(1000); // Wait for a second
        sucess = false;
    }
}

关于java - 面对多线程堆栈跟踪 - 该进程无法访问该文件,因为它正被另一个进程使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22313522/

相关文章:

java - Spring 集成卡夫卡消费者

java - Android 中的函数重用

具有长时间运行计时器的 Python 线程意外退出

C++ TLS,有问题

java - 传递 String str=null 时输出为 null

java - 为后台线程创建 JPA session

java - 在 java.time 中,为什么 WeekFields.SUNDAY_START 会为 2020-12-29 生成周数 1 而不是 53?

java - 异常后的线程处理

python - 为什么 asyncio.get_event_loop 方法检查当前线程是否为主线程?

java - 有没有一种安全正确的方法来使用Java语言杀死Windows中的进程树