Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.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_Locking_Fileinputstream_Filechannel - Fatal编程技术网

Java文件通道保持锁定文件

Java文件通道保持锁定文件,java,locking,fileinputstream,filechannel,Java,Locking,Fileinputstream,Filechannel,希望有人能解释我做错了什么。 我有一个创建FileInputStream的DataLoader类。由于FileInputStream实现了Closeable,所以我将该实例创建为try块的一部分。 然后,我将新创建的流传递给DataManager类。这个类打开一个文件通道并将数据读入一个单例类,将所有数据存储到内存块中。由于FileChannel还实现了Closeable,所以我也在try块中实例化它 然后,我从一个线程调用这段代码,检查是否有任何文件更改,当这种情况发生时,将创建DataLoa

希望有人能解释我做错了什么。

我有一个创建FileInputStream的DataLoader类。由于FileInputStream实现了Closeable,所以我将该实例创建为try块的一部分。

然后,我将新创建的流传递给DataManager类。这个类打开一个文件通道并将数据读入一个单例类,将所有数据存储到内存块中。由于FileChannel还实现了Closeable,所以我也在try块中实例化它

然后,我从一个线程调用这段代码,检查是否有任何文件更改,当这种情况发生时,将创建DataLoader的一个新实例来重建内存块。但由于文件锁定,此操作经常失败。此代码是运行在windows 10上的Java 1.8标准应用程序的一部分。我是否错误地假设文件通道和文件输入流都关闭了?我在两个类中都添加了调用close方法的代码,但没有成功

任何帮助都将不胜感激。提前谢谢

public class DataManager {

    public DataManager(FileInputStream in) throws IOException {
        fromInputStream(in);
    }

    public final void fromInputStream(FileInputStream in) throws IOException {
        try (FileChannel ch = in.getChannel()) {
            MappedByteBuffer mb = ch.map(MapMode.READ_ONLY, ch.position(), ch.size());
            readData(mb); //reads mapped buffer into a byte array, e.g.: mb.get(barray, 0, 1000);
        }
    }

}

public class DataLoader {

    public DataLoader(File binFile) throws FileNotFoundException, IOException {
        try (FileInputStream in = new FileInputStream(binFile)) {
            DataManager d = new DataManager(in);
        } catch (Exception e) {
            LOG.error("Something went wrong while loading data.", e);
        }
    }

}

正如评论中所建议的,这个问题取决于windows对FileChannel的使用有点严格。我用InputStream替换了所有与FileChannel相关的代码,锁定行为消失了。

在Windows上以及在取消映射字节缓冲区时,有各种各样的问题提到。另请参见[JDK-4715154][1]——这是映射后删除文件的相关问题。如果
MappedByteBuffer
在使用后未进行垃圾收集,则文件上可能存在延迟锁定,这会阻止其他Java/Windows应用程序访问该文件,即使在您最后尝试(关闭)之后也是如此。[1] :谢谢你的提示。我将更改代码以避免使用MappedByteBuffer,并查看问题是否消失。我想知道gc,我有一个想法,就是将MappedByteBuffer变量设置为null,只是为了提示gc(甚至更多)没有引用被保存,并将MappedByteBuffer更改为弱变量(不确定我是否可以在没有类成员的情况下执行此操作)。好吧,我最终删除了FileChannel并直接处理FileInputStream。这解决了锁定行为。谢谢