5

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

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

目前我正在考虑stat()使用 JNA 实现调用,但这似乎有点过头了,因为必须实现整个统计结构和所有__xstat64看起来如此依赖于平台的东西。

errno有没有一种简单的方法可以在 Java 调用或任何其他想法之后简单地获取底层File.exists()来解决这个问题?

4

2 回答 2

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();
    ...
}
于 2013-05-30T14:59:35.913 回答
1

如果您的性能要求很低,我将只实现一个小型 C 程序,它调用stat给定的文件名并将值打印errno到标准输出。然后从 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");
  }
}

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

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

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

于 2013-05-30T13:25:54.807 回答