我正在尝试在NFS文件系统上编写在Linux环境中运行的Java应用程序。
我注意到,当我调用java.io.File.exists()
时,它会为ESTALE
(过时的NFS文件句柄)和ENOENT
(没有这样的文件或目录)返回false。对于我的应用程序,我需要能够区分这两者。
目前我正在考虑使用JNA实现stat()
调用,但这似乎有些过分,需要实现整个统计结构和所有__xstat64
看起来与平台相关的东西。< / p>
有一种简单的方法可以在像errno
之类的Java调用之后简单地获取基础File.exists()
或者解决这个问题的任何其他想法吗?
答案 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方式。