2013-03-07 2 views
3

DICOM 파일을 읽는 응용 프로그램을 작성하고 있으므로 다른 라이브러리를 사용해야합니다. 라이브러리가 파일을 열지 만 파일을 닫으면 파일을 닫지 않습니다. 그리고 도서관은 오픈 소스가 아닙니다. 열린 파일 제한은 리눅스에서 1024이며, 번호를 변경할 수 있다는 것을 알고 있습니다. 그러나 나는 그 길을하고 싶지 않습니다. 나는 도서관에 의해 열린 파일을 닫고 싶다. C가 열리는 것을 알고 있으면 C에서 파일을 닫는 방법. 나는 http://cbi.nyu.edu/software/dinifti.php에서 얻은 DICOM2NII 라이브러리를 사용하고 있습니다. 는 그리고이 파일을 열 수있는 코드이지만이미 열려있는 C에서 파일을 닫는 방법

bool DICOMImage::OpenFile(const char *path) 
{ 
    bool retValue = true; 
    DCM_Objects handle_; 
    unsigned long options = DCM_ORDERLITTLEENDIAN | DCM_FORMATCONVERSION | DCM_VRMASK; 
    // Try opening as PART10, if it fails it's might be bcause it does not have 
    // a preable and the try it that way 
    if (DCM_OpenFile(path, options | DCM_PART10FILE, &handle_) != DCM_NORMAL) 
    { 
     DCM_CloseObject(&handle_); 
     COND_PopCondition(TRUE); 
     if (DCM_OpenFile(path, options, &handle_) != DCM_NORMAL) 
     {  
      retValue = false; 
     } 
     else 
      retValue=true; 
    } 

    return retValue; 
} 
+2

파일을 다 읽었을 때 파일을 닫을 때 라이브러리가 별도의 기능을 제공하지 않습니까? –

+0

예. 이 헤더 파일에서 찾을 수 있지만 가지고 있지 않습니다. 이것은 주된 문제입니다 – user2143123

+0

라이브러리 소스가 사용 가능해 보입니다 (ftp://ftp.erl.wustl.edu/pub/dicom/software/ctn/). 또한'DCM_OpenFile()'이'DCM_FILEACCESSERROR' 오류를 반환 할 때 파일 핸들을 누출시킬 수 있지만'fstat()'에 대한 호출이 실패하거나 파일의 크기가'INT_MAX'보다 클 경우에만 발생합니다 그게 당신이 달리고있는 것입니까?). 무의미한 말로,'DCM_OpenFile()'은 파일을 여는 것보다 더 많은 일을하기 때문에 (실제로 파일이 끝나면 파일을 닫을 것입니다) 이름이 잘못 붙어있는 것 같습니다. –

답변

1

가 먼저 getdtablesize()까지 0에서 모든 FD에 더미 fcntl(fd, F_GETFD)을 수행하여 사용되는 것을보기 위해 모든 파일 디스크립터를 테스트 할 수 닫히지 않습니다. 라이브러리 함수가 돌아 오면 close()으로 닫을 수있는 fd가 하나 더 생깁니다. 이전에 열지 않은 모든 항목에 close(fd)으로 전화를 걸면 그 중 하나가 성공합니다 (검색시 그 시점에서 중지 할 수 있음).

초기 프로브를 사용하지 않은 첫 번째 fd까지 수행 할 수 있고 라이브러리는 하나의 파일을 열 때보 다 복잡한 작업을 수행하지 않는다면 해당 fd를 사용하여 끝납니다. 여러 파일을 열거 나 dup()을 사용하면 다른 곳에서 끝날 수 있습니다.

이 밖으로 철자하려면 다음 파일을 닫습니다

DICOMImage::DICOMImage() : handle_(0) { ... } 

DICOMImage::~DICOMImage() { 
    if (handle_ != 0) 
     DCM_CloseObject(&handle_); 
} 

을 회원

DCM_OBJECT *handle_; 

을 추가하고 소멸자에, 당신의 DICOMImage 클래스에서

#include <iostream> 
#include <vector> 
#include <unistd.h> 
#include <fcntl.h> 

std::vector<bool> getOpenFileMap() 
{ 
    int limit = getdtablesize(); 
    std::vector<bool> result(limit); 

    for (int fd = 0; fd < limit; ++fd) 
     result[fd] = fcntl(fd, F_GETFD) != -1; 
    return result; 
} 

void closeOpenedFiles(const std::vector<bool> &existing) 
{ 
    int limit = existing.size(); 
    for (int fd = 0; fd < limit; ++fd) 
     if (!existing[fd]) 
      close(fd); 
} 

int getLikelyFd() 
{ 
    int limit = getdtablesize(); 

    for (int fd = 0; fd < limit; ++fd) 
     if (fcntl(fd, F_GETFD) != -1) 
      return fd; 
} 

int main() 
{ 
    std::vector<bool> existing = getOpenFileMap(); 
    int fd = open("/dev/null", O_RDONLY); 
    closeOpenedFiles(existing); 
    bool closed = write(fd, "test", 4) == -1; 
    std::cout << "complex pass " << std::boolalpha << closed << std::endl; 

    int guess = getLikelyFd(); 
    fd = open("/dev/null", O_RDONLY); 
    bool match = fd == guess; 
    std::cout << "simple pass " << std::boolalpha << match << std::endl; 
} 
+0

fd 매개 변수 란 무엇입니까? 왜냐하면 라이브러리의 함수 열기가 정상적으로 작동하지 않기 때문입니다. #include fcntl (fd, F_GETFD) 닫기 (fd). 그리고 Kdevelop가 오류를 알려줍니다 : 'fd'가이 범위에서 선언되지 않았습니다 – user2143123

+0

@ user2143123 : 알았어, 철자가 틀림. –

+0

감사합니다. 그것은 잘 작동합니다. 나는 int guess = getLikelyFd(); 닫기 (추측); – user2143123

2

및이 멤버를 사용 handle_ 물론 DICOMImage::OpenFile()에도 있습니다.

관련 문제