2013-05-30 2 views
5

리눅스 환경에서 실행중인 Java 응용 프로그램을 NFS 파일 시스템에 쓰려고합니다.Java에서 ESTALE과 ENOENT를 구별하는 가장 좋은 방법

java.io.File.exists()을 호출하면 ESTALE (부적절한 NFS 파일 핸들)과 ENOENT (해당 파일이나 디렉토리가 없음) 모두에 대해 false가 반환됩니다. 내 응용 프로그램의 경우이 둘을 구별 할 수 있어야합니다.

현재 stat() 호출을 JNA를 사용하여 구현할 것을 고려 중입니다.하지만 과장 될 것으로 보입니다. 전체 stat 구조를 구현해야하는 이유와 플랫폼에 따라 달라지는등이 있습니다.

File.exists() 같은 Java 호출 후에 기본 errno을 얻는 간단한 방법이나이 문제를 해결하기위한 다른 아이디어가 있습니까?

답변

2

JNA를 사용하면 실질적으로 stat 구조를 구현할 필요가 없습니다. 네이티브 구조를 표현하기에 충분히 큰 메모리를 할당하면됩니다.

을 호출하면 errno 값을 검색 할 수 있습니다.

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

나는이 제안을 좋아한다. 나는 또한'access (file, F_OK)'를 구현하는 것을 고려했다. 이것은 훨씬 간단하지만'ESTALE'과'ENOENT'를 구별하지 못한다. 그러나 결국 우리는 이러한 차별화를 필요로하지 않는 솔루션을 발견했습니다. –

1

성능 요구 사항이 낮은 경우 주어진 파일 이름에 stat을 호출하고 errno의 값을 stdout에 인쇄하는 작은 C 프로그램을 구현하기 만하면됩니다. 그런 다음 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에서 소켓을 사용하여 통신하도록하십시오. 또는 아파치에서 CGI 스크립트로 사용하고 Java에서 HTTP를 사용하도록합니다.

여전히 너무 느린 경우 JNI/JNA 방식으로 이동해야합니다.