C언어

[APR] file handling

고요한하늘... 2009. 1. 23. 14:11

파일 처리

파일을 다룰때 apr_file_open()을 처음에 호출해야 한다.  간단한 프로토 타입을 보면

 

apr_file_open(apr_file_t **newf, const char *fname, apr_int32_t flag, apr_fileperms_t perm, apr_pool_t *pool);


첫번째 아규먼트 타입은 apr_file_t **로써 결과 값이다.
즉 apr_file_open()를 호출하면 apr_file_t 오브젝트가 생성된다.
두번재 아규먼트는 파일 경로
세번째 아규먼트는 플래그( bit -wised ), 비트 관련은 apr_file_io.h에 정의돼 있다.
네번재 아규먼트는 파일 접근 권한으로 새로 파일을 생성할때 관련이 있다. 그 값은 bit-wised 플래그이다.


0600 파일 권한으로 파일 생성을 원한다면( 파일 소유자만 읽기/쓰기가 가능한 ) APR_USEAD|APR_UWRITE를 구체적으로 명시해야 한다. 이런 경우 APR_OS_DEFAULT로 파일 권한을 설명하면 된다.
네번재 파일 아규먼트는 사용할 메모리 풀이다. 두말할 나위 없이 apr_pool_create()로 메모리 풀을 생성한다.

파일을 오픈한 후에 다른 APIs로 파일을 다룰수 있다. apr_file_io.h에 api들이 있다
기본적인 API는 apr_file_read(), apr_file_write()이다.
알다 시피 apr_file_read()는 파일로 부터 어떤 것을 읽기 위한 것이고, apr_file_write()는 파일에 어떤것을 쓰기 위한 것이다.

프로토 타입을 보면


apr_file_read(apr_file_t *thefile, void *buf,  apr_size_t *nbytes);
apr_file_write(apr_file_t *thefile, const void *buf,  apr_size_t *nbytes);


두 함수의 세번째 아규먼트는 결과값이다. 그것은 입력 값의 길이와 출력값의 길이를 명시해야 하는 것을 의미한다.
특히 apr_file_read()읽은 바이트수를 apr_file_write()를 쓴 바이트수를 리턴한다.

 

/* pseudo code about apr_file_write() */
strcpy(outbuf, "123456789");
apr_size_t outlen = strlen(outbuf);
rv = apr_file_write(fp, outbuf, &outlen);
printf("apr_file_write() rv = %d, nbytes = %d\n", rv, outlen);

 

 

outlen변수값을 9로 한 이후에 apr_file_write()를 호출한다. outlen을 9로 설정하고 apr_file_write()호출하는 것은  API에서 쓸(write) 수 있는 길이는 9라는 것이다.

apr_file_write()가 실행된 후에 outlen은 실제로 write한 길이가 된다. 보통 로컬 파일에 쓰면 outlen은 9가 간다. 이론적으로 그것보다 작은수 있는데 ( disk full 같은 경우에 )

파일을 닫기 위해서는 apr_file_close()를 호출한다 .apr_file_open()을 통해서 파일을 열고 메모리 해제로 파일을 닫는것보다는 명시적으로 apr_file_close()를 호출하는게 좋다.

 

주의 : libapr 버전가운데 몇몇의 소스는 이식성 문제가 있다. apr_file_open()의 세번째 아규먼트 APR_FOEN_이라는 접두사는 libapr-1.1.0 이후에 붙었다. APR_CREATE대신에 APR_FOPEN_CREATE를 사용해야 한다. 사용중인 apr_file_io.h에서 확인해라. 비슷한 문제로 apr_file_open()의 네번째 아규멘트는 APR_FPROT_라는 접두사는 libapr-1.1.0이후에 붙었다.

 

주의 : 파일 구분자에 대한 이식성 문제가 있다. 유닉스에서는 슬래시를 윈도우에서는 백슬래시를 구분자로 사용한다. 윈도우와 유닉스를 같이 사용한다면, 파일 구분자를 슬래시로 표준화해서 사용하는것을 추천한다. 윈도우에서도 이것은 허용한다.


주의 : apr_file_gets()사용법을 주의해서 봐라. apr_file_gets() 을 APR_BUFFRED없이 호출하면 성능에 심각히 떨어진다. apr_file_gets()은 내부적으로 apr_file_read()를 1byte 마다 호출하기 때문이다. apr_file_gets()를 사용하기 위해서는 APR_BUFFERED 플래그를 사용해서 파일을 열어라.

 

다음과 같은 경우를 제외하고 APR_BUFFERED를 사용하는게 좋다.

mmap을 사용할때( mmap에서 APR_BUFFERED를 사용하면 에러가 발생한다 )
일기/쓰기가 없을때( 파일을 락 목적으로 사용할때 )
충분히 큰 버퍼로 읽기/쓰기를 할 경우

 

주의 : APR_BUFFERED로 파일을 열고, apr_file_trunc()를 호출하면, apr_file_trunc()를 호출하기 전에  apr_file_flush()를 호출해야 한다. 그렇지 않으면 파일이 깨진다.


주의 : APR_BUFFERED로 파일을 열고, 파일이 멀티쓰레드로 공유한다면 APR_XTHREAD플래르가 필요하다. 불행히도 APR_XTHREAD플래는 윈도우에서 side effect가 발생한다. 경험상 윈도우에서는 APR_XTHREAD플래그는 사용하지 않는게 좋다.

 

파일 크기나, 시간 정보, 소유권, 접근 권한 등등 정보를 얻을수도 있다. apr_finfo_t 구조체에 그런 정보들이 잇는데 apf_file_info.h에서 찾을수 있다. 관련된 두개의 API를 보면

 

 apr_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted, apr_file_t *thefile);

 apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool);

 

apr_file_info_get()을 apr_file_t 오브젝트를 가 필요하다 apr_stat()는 파일명이 필요하다. 파일이 이미 열려져 있다면 apr_file_t 오브젝트를 가지고 있을 것이고 이럴 경우 apr_file_info_get()을 사용하는게 좋다. 아니면 apr_stat()를 호출해라. 다른 타입들과는 다르게 apr_finfo_t는 완전한 타입이다. 오브젝트를 만들기 위한 API를 호출하는 것보다, 명시적으로 apr_finfo_t를 할당받는것이 좋다. 시간정보나 파일 크기와 같은 몇몇 속성들을 알기 위해서 보통 로컬 스택에 할당한다.
apr_finfo_t:fname 과 같은 몇몇 메모리들은 메모리 풀에 할당된다. 이것은 심각한 버그를 야기하는데, 주의 깊게 finfo-sample.c의 사용예를 확인해봐라

파일명을 가지고 파일을 다루는  API들이 있다. 예를 들면 apr_file_remove(), apr_file_copy(). apr_file_io.h, apr_file_info.h에서 확인할수 있다.

 

주의 : 몇몇 API들은 파일 정보를 얻기 위해 bit-wised 플래그를 명시적으로 사용하는 'wanted' 아규멘트를 가지고 있다. apr_dir_read(), apr_stat(), apr_lstat(), apr_file_info_get()들이 이 그런함수이다. 'wanted' 아규멘트 값은 OS 파일 시스템지원을 넘어선다. 이럴 경우  API는 APR_INCOMPLETE를 리턴한다.
 

'C언어' 카테고리의 다른 글

warning assignment makes pointer from integer without a cast  (0) 2009.01.30
[APR] Container APIs  (0) 2009.01.29
[APR] memory pool  (0) 2009.01.22
apache 코어 설정  (0) 2009.01.22
apr Makefile 만들기  (0) 2009.01.22