检查 Linux NFS 上文件是不是存在的任何可靠方法? [复制]

     2023-02-16     59

关键词:

【中文标题】检查 Linux NFS 上文件是不是存在的任何可靠方法? [复制]【英文标题】:Any sure fire way to check file existence on Linux NFS? [duplicate]检查 Linux NFS 上文件是否存在的任何可靠方法? [复制] 【发布时间】:2011-09-22 03:06:35 【问题描述】:

我正在开发一个需要检查文件是否存在的 Java 程序。

好吧,很简单,代码调用File.exists() 来检查文件是否存在。我遇到的问题是,它报告误报。这意味着该文件实际上并不存在,但exists() 方法返回true。没有捕获到异常(至少没有像“Stale NFS 句柄”这样的异常)。该程序甚至设法通过InputStream 读取文件,按预期获得0 字节,但没有例外。目标目录是 Linux NFS。而且我 100% 确定要查找的文件永远不存在。

我知道java.io.File.exists() 存在已知的错误(某种 API 限制)。因此,我通过使用 Linux 命令ls 检查文件是否存在添加了另一种方法。 Java 代码现在不再调用File.exists(),而是运行一个Linux 命令到ls 目标文件。如果退出代码是0,则文件存在。否则文件不存在。

随着技巧的引入,该问题的出现次数似乎减少了,但仍然会出现。同样,在任何地方都没有捕获到错误(这次是标准输出)。这意味着问题非常严重,即使是原生 Linux 命令也无法 100% 修复。

所以有几个问题:

    我相信 Java 在File.exists() 上的众所周知的问题是关于报告假阴性。报告文件不存在但实际上确实存在的位置。由于 API 不会为 File.exists() 抛出 IOException,因此它选择在对 OS 底层本机函数的调用失败的情况下吞下异常,例如NFS 超时。但这并不能解释我遇到的误报案例,因为该文件永远不存在。这个有什么推荐的吗? 我对Linuxls退出码的理解是,0表示ok,相当于文件存在。这种理解是错误的吗? ls 的手册页对退出代码含义的解释不是很清楚:退出状态是 0 如果 OK,1 如果是小问题,2 如果是大问题。 好的,回到主题。在 Linux 上使用 Java 检查文件是否存在的任何可靠方法?在我们看到带有 NIO2 的 JDK7 正式发布之前。

【问题讨论】:

您是否在检查文件是否存在的同一进程中创建和删除文件?如果文件从未存在,您永远不应该得到说文件存在的东西,但如果它最近被删除,那么您可能会得到不同的行为(如 .nfs923126 文件) File.isFile 表现更好吗? 感谢所有回复。我想我刚刚弄清楚为什么我得到了假阳性结果。确实不是 File.exists() 不起作用,而是自制后台文件阅读器中的竞争条件导致文件读取在没有文件的情况下继续。我刚刚修复了阅读器,现在就我的测试而言,一切都回到了正轨。 Otto,你是对的,如果一个文件最近存在并被删除,它可能会表现出误报行为。但我认为这种情况在我的环境中不存在,现在最新一轮的测试结果进一步证实了这一点。再次感谢大家的贡献。我希望 JDK7 现在可以发布,它可以通过从可疑列表中删除有问题的 java.io 来节省我的一些时间:P 如果 7 可能需要永远发布,他们为什么不直接支持 NIO2?嗯?开个玩笑,各种:) Alternative to File.exists() in Java 的副本 【参考方案1】:

这是一个显示问题的 JUnit 测试和一些实际尝试读取文件的 Java 代码。

问题发生,例如在 OSX Mavericks 上使用 Samba。一个可能的原因 由以下语句解释: http://appleinsider.com/articles/13/06/11/apple-shifts-from-afp-file-sharing-to-smb2-in-os-x-109-mavericks

它积极缓存文件和文件夹属性,并使用机会锁定来更好地缓存数据。

请在下面找到一个 checkFile,它实际上会尝试读取几个字节并强制进行真正的文件访问以避免缓存错误行为...

JUnit 测试:

/**
 * test file exists function on Network drive replace the testfile name and ssh computer
     * with your actual environment
 * @throws Exception
 */
@Test
public void testFileExistsOnNetworkDrive() throws Exception 
    String testFileName="/Volumes/bitplan/tmp/testFileExists.txt";
    File testFile=new File(testFileName);
    testFile.delete();
    for (int i=0;i<10;i++) 
        Thread.sleep(50);
        System.out.println(""+i+":"+OCRJob.checkExists(testFile));
        switch (i) 
        case 3:
            // FileUtils.writeStringToFile(testFile, "here we go");
            Runtime.getRuntime().exec("/usr/bin/ssh phobos /usr/bin/touch "+testFileName);
            break;
        
    

checkExists 源代码:

/**
 * check if the given file exists
 * @param f
 * @return true if file exists
 */
public static boolean checkExists(File f)  
    try 
        byte[] buffer = new byte[4];
        InputStream is = new FileInputStream(f);
        if (is.read(buffer) != buffer.length)  
            // do something 
        
        is.close();
        return true;
     catch (java.io.IOException fnfe) 

    
    return false;

【讨论】:

【参考方案2】:

JDK7 是几个月前发布的。 Files 类中有 existsnotExists 方法,但它们返回 boolean 而不是抛出异常。如果您确实想要异常,请使用FileSystems.getDefault().provider().checkAccess(path),如果文件不存在,它将引发异常。

【讨论】:

是的,这也是我从 Sun 的错误帖子中读到的内容。使用 File.toPath().checkAccess()。很高兴听到 JDK7 发布了。谢谢。 这在网络文件方案中无法按预期工作。Path path=FileSystems.getDefault().provider().getPath(f.toURI()); FileSystems.getDefault().provider().checkAccess(path,AccessMode.READ);在我的答案中的 JUnit 测试用例中将失败。【参考方案3】:

如果您需要健壮,请尝试读取文件 - 如果文件不存在(或存在权限或其他问题),则优雅地失败。这也适用于 Java 以外的任何其他语言。

判断文件是否存在并且您可以从中读取的唯一安全方法是从文件中实际读取数据。无论文件系统是本地的还是远程的。原因是在您从checkAccess(path) 获得成功后可能会立即发生竞争条件:检查,然后打开文件,您会发现它突然不存在。其他一些线程(或另一个远程客户端)可能已将其删除,或已获得排他锁。所以不要费心检查访问,而是尝试读取文件。花时间运行ls 只是让比赛条件窗口更容易适应。

【讨论】:

如何在 C 代码中检查目录是不是在 NFS 文件系统上?

】如何在C代码中检查目录是不是在NFS文件系统上?【英文标题】:HowtocheckinCcodewhetheradirectoryisonNFSfilesystem?如何在C代码中检查目录是否在NFS文件系统上?【发布时间】:2012-07-2808:22:47【问题描述】:在我的C/C++程序中,我想检查... 查看详情

检查 NFS 共享是不是在 PHP 中启动

】检查NFS共享是不是在PHP中启动【英文标题】:CheckifNFSshareisupinPHP检查NFS共享是否在PHP中启动【发布时间】:2010-11-1213:52:22【问题描述】:我正在开发一个存储上传文件的系统。元数据将进入本地可访问的数据库,但文件本身将... 查看详情

C中是不是有任何NFS实现? [关闭]

】C中是不是有任何NFS实现?[关闭]【英文标题】:isthereanyNFSimplementationinC?[closed]C中是否有任何NFS实现?[关闭]【发布时间】:2013-02-2717:28:32【问题描述】:我正在用C编写自己的NFS(网络文件系统)实现。是否有任何好的可用资... 查看详情

使用 BATCH 脚本检查目录中是不是存在任何类型的文件

】使用BATCH脚本检查目录中是不是存在任何类型的文件【英文标题】:CheckifanytypeoffilesexistinadirectoryusingBATCHscript使用BATCH脚本检查目录中是否存在任何类型的文件【发布时间】:2012-06-0413:11:57【问题描述】:您好,我正在寻找一... 查看详情

linux网络文件系统nfs详解(代码片段)

...朋友给你闹,你就不性福了哈哈,所以我们很容易想到,是不是可以把文件上传到一个公用的服务器上呢?这样不管访问的是A还是B,读、取文件都只存在一份 查看详情

检查文件夹中是不是存在任何文件(VBScript)

】检查文件夹中是不是存在任何文件(VBScript)【英文标题】:Checktoseeifanyfileexistswithinafolder(VBScript)检查文件夹中是否存在任何文件(VBScript)【发布时间】:2011-10-0905:07:13【问题描述】:如何检查文件夹中是否存在任何名称的... 查看详情

如何以编程方式确定文件是不是位于 Linux 和/或 macOS 的网络文件系统(NFS 或 SMB)上?

】如何以编程方式确定文件是不是位于Linux和/或macOS的网络文件系统(NFS或SMB)上?【英文标题】:HowcanIdetermine,programatically,ifafileislocatedonanetworkfilesystem(NFSorSMB)inLinuxand/ormacOS?如何以编程方式确定文件是否位于Linux和/或macOS的网络... 查看详情

linux下的nfs搭建配置

...介2.NFS特点二、环境介绍三、服务端配置1.创建共享目录2.检查NFS包是否安装3.编辑配置文件4.重启服务且放行防火墙四、客户端配置1.检查服务端共享目录是否存在2.安装自动挂载程序2.启动服务3.编辑配置文件五、检查测试一、NFS... 查看详情

如何检查 csh 脚本中是不是存在任何文件?

】如何检查csh脚本中是不是存在任何文件?【英文标题】:howtocheckexistenceofanyfileincshscript?如何检查csh脚本中是否存在任何文件?【发布时间】:2015-03-0501:42:15【问题描述】:为了检查我正在使用的csh脚本中是否存在任何文件if[-f... 查看详情

检查 FTP 服务器上的文件是不是存在

】检查FTP服务器上的文件是不是存在【英文标题】:CheckingfileexistenceonFTPserver检查FTP服务器上的文件是否存在【发布时间】:2012-05-1523:14:08【问题描述】:有没有一种有效的方法来检查FTP服务器上的文件是否存在?我正在使用Apac... 查看详情

检查文件是不是存在Linux bash [重复]

】检查文件是不是存在Linuxbash[重复]【英文标题】:CheckiffileexistLinuxbash[duplicate]检查文件是否存在Linuxbash[重复]【发布时间】:2012-05-2616:10:40【问题描述】:所以我正在尝试检查文件是否存在,如果存在,脚本应该执行某些操作... 查看详情

检查 FTPS 上是不是存在文件,错误 550

】检查FTPS上是不是存在文件,错误550【英文标题】:CheckiffileexistsonFTPS,Error550检查FTPS上是否存在文件,错误550【发布时间】:2013-10-2412:54:39【问题描述】:我试图检查我的FTP服务器上是否存在文件,但我收到错误“远程服务器... 查看详情

nfs详解(代码片段)

...非必要,管理文件锁,避免同时写出错rpc.statd:非必要,检查文件一致性,可修复文件nfs的关键工具包括:主要配置文件:/etc/exports;NFS文件系统维护命令:/usr/bin/exportfs;共享资源的日志文件:/var/lib/nfs/*tab;客户端查询共享... 查看详情

如何检查Golang目录中是不是存在文件`name`(带有任何扩展名)?

】如何检查Golang目录中是不是存在文件`name`(带有任何扩展名)?【英文标题】:Howtocheckfile`name`(withanyextension)doesexistinthedirectoryinGolang?如何检查Golang目录中是否存在文件`name`(带有任何扩展名)?【发布时间】:2017-12-2021:17:52... 查看详情

检查 NFS 共享是不是安装在 python 脚本中

】检查NFS共享是不是安装在python脚本中【英文标题】:CheckifNFSshareismountedinpythonscript检查NFS共享是否安装在python脚本中【发布时间】:2010-05-2219:32:45【问题描述】:我编写了一个python脚本,它依赖于某个可用的NFS共享。如果NFS共... 查看详情

当 NFS 挂载失败时,bash 检查目录是不是存在挂起

】当NFS挂载失败时,bash检查目录是不是存在挂起【英文标题】:bashcheckingdirectoryexistencehangingwhenNFSmountgoesdown当NFS挂载失败时,bash检查目录是否存在挂起【发布时间】:2012-02-0612:06:38【问题描述】:我有一个.bash_profile脚本,它根... 查看详情

检查linux脚本中是不是存在文件[重复]

】检查linux脚本中是不是存在文件[重复]【英文标题】:Checkifafileexistsinalinuxscript[duplicate]检查linux脚本中是否存在文件[重复]【发布时间】:2013-12-0713:01:24【问题描述】:我制作了一个linux脚本,它接收一个目录路径作为第一个参... 查看详情

如何检查 FTP 服务器上是不是存在文件?

】如何检查FTP服务器上是不是存在文件?【英文标题】:HowcanIcheckifafileexistsonFTPserver?如何检查FTP服务器上是否存在文件?【发布时间】:2011-11-1622:33:30【问题描述】:我在android上使用apacheFTPClient。我想从ftp服务器下载一个文件... 查看详情