在Java中区分ESTALE和ENOENT的最佳方法

时间:2013-05-30 10:54:16

标签: java jna nfs

我正在尝试在NFS文件系统上编写在Linux环境中运行的Java应用程序。

我注意到,当我调用java.io.File.exists()时,它会为ESTALE(过时的NFS文件句柄)和ENOENT(没有这样的文件或目录)返回false。对于我的应用程序,我需要能够区分这两者。

目前我正在考虑使用JNA实现stat()调用,但这似乎有些过分,需要实现整个统计结构和所有__xstat64看起来与平台相关的东西。< / p>

有一种简单的方法可以在像errno之类的Java调用之后简单地获取基础File.exists()或者解决这个问题的任何其他想法吗?

2 个答案:

答案 0 :(得分:2)

使用JNA,您实际上不必实现stat结构;你只需要分配足够大的内存来代表本机结构。

然后,您可以致电Native.getLastError()以检索errno值。

Pointer fake_stat = new Memory(2048); // big enough
if (clib.stat(filename, fake_stat) != 0) {
    int errno = Native.getLastError();
    ...
}

答案 1 :(得分:1)

如果你的性能要求很低,我只会实现一个小的C程序,它为给定的文件名调用stat并将值errno打印到stdout。然后从Java调用它:

#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>

int main(int argc, char * argv[]) {
  struct stat buf;
  char const * const fileName = argv[1];
  int const ret = stat(fileName, &buf);
  printf("File %s: Return %d, errno %d\n", fileName, ret, errno);
  if (errno) {
    perror("Error");
  }
}

从命令行,这需要4毫秒。在您的情况下,如果之前的exists()返回false,则可能只需要调用它。

其他可能性:考虑将其包装在一个小型TCP服务器中,让Java使用套接字与它通信。或者在apache中将其用作CGI脚本,让Java使用HTTP。

如果这仍然太慢,你可能必须采用JNI / JNA方式。