함수 C에서 파일의 크기를 어떻게 결정합니까?




fwrite (11)

바이트의 파일 크기를 어떻게 알 수 있습니까?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}

이 코드 세트를 사용하여 파일 길이를 찾았습니다.

//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");

//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);

//stores file size
long file_length = buffer.st_size;
fclose(i_file);

그리고 Windows 응용 프로그램을 만드는 경우 GetFileSizeEx API를 CRT 파일 입출력이 지저분하므로 특히 다른 시스템에서 파일 표현의 특성으로 인해 파일 길이를 결정할 때 혼란 스럽습니다.


이 시도 --

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

이것이 무엇을하는지 먼저, 파일의 끝에 추구; 그런 다음 파일 포인터가있는 위치를보고하십시오. 마지막으로 (선택 사항) 파일의 시작 부분으로 되감습니다. fp 는 이진 스트림이어야합니다.

file_size는 파일에 들어있는 바이트 수를 포함합니다. unsigned long 타입은 4294967295 바이트 (4 기가 바이트)로 제한되므로 (climits.h에 따라)보다 큰 파일을 처리 할 가능성이있는 경우 다른 변수 유형을 찾아야합니다.


**이 작업을 수행하지 마십시오 ( why? ) :

온라인에서 찾은 C99 표준 문서 인용 : "파일 위치 표시기를 fseek (파일, 0, SEEK_END)와 같이 파일 끝으로 설정하면 이진 스트림의 정의되지 않은 동작이 발생할 수 있습니다 (뒤 따르는 null 문자로 인해). 초기 시프트 상태에서 확실하게 끝나지 않는 상태 종속적 인 인코딩을 가진 스트림의 경우. **

오류 메시지를 전송할 수 있도록 정의를 int로 변경 한 다음 fseek () 및 ftell ()을 사용하여 파일 크기를 결정합니다.

int fsize(char* file) {
  int size;
  FILE* fh;

  fh = fopen(file, "rb"); //binary mode
  if(fh != NULL){
    if( fseek(fh, 0, SEEK_END) ){
      fclose(fh);
      return -1;
    }

    size = ftell(fh);
    fclose(fh);
    return size;
  }

  return -1; //error
}

std c 라이브러리를 사용하는 것이 괜찮 으면 :

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

파일을 열 수 있으며 파일의 아래쪽에있는 0 오프셋을 사용하여 이동할 수 있습니다.

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

fseek에서 반환 된 값은 파일의 크기입니다.

나는 오랫동안 C 언어로 코드를 작성하지 않았지만 작동해야한다고 생각합니다.


매트의 해결책은 C가 아니라 C ++이고, 초기 말은 필요하지 않아야한다는 것을 제외하고는 작동해야합니다.

unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}

당신을 위해 중괄호도 수정했습니다. ;)

업데이트 : 이것이 최고의 솔루션은 아닙니다. Windows에서 4GB 파일로 제한되며 GetFileSizeEx 또는 stat64 와 같은 플랫폼 관련 호출을 사용하는 것보다 속도가 느릴 수 있습니다.


질문을 보면, ftell 은 바이트 수를 쉽게 얻을 수 있습니다.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

NilObject의 코드를 기반으로 :

#include <sys/stat.h>
#include <sys/types.h>

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

변경 사항 :

  • filename 인수를 const char 만들었습니다.
  • 변수 이름이 누락 된 struct stat 정의를 수정했습니다.
  • 빈 파일에 대해 모호한 0 대신 오류 -1 을 반환합니다. off_t 는 서명 된 유형이므로 가능합니다.

fsize() 가 에러시 메시지를 출력하게하려면 다음과 같이하면됩니다 :

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
    struct stat st;

    if (stat(filename, &st) == 0)
        return st.st_size;

    fprintf(stderr, "Cannot determine size of %s: %s\n",
            filename, strerror(errno));

    return -1;
}

32 비트 시스템에서는 -D_FILE_OFFSET_BITS=64 옵션을 사용하여 컴파일해야합니다. 그렇지 않으면 off_t 는 최대 2GB의 값만 보유합니다. 자세한 내용은 Linux대용량 파일 지원 의 "LFS 사용"절을 참조하십시오.


다음은 파일 크기를 반환하는 간단하고 깨끗한 함수입니다.

long get_file_size(char *path)
{
    FILE *fp;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    return ftell(fp); 
}

int 사용하지 마십시오. 크기가 2 기가 바이트를 넘는 파일은 요즘 흔히 볼 수 있습니다.

unsigned int 사용하지 마십시오. 크기가 4 기가 바이트를 넘는 파일은 약간 덜 일반적인 먼지처럼 일반적입니다.

IIRC 표준 라이브러리는 off_t 를 모든 사람이 사용해야하는 부호없는 64 비트 정수로 정의합니다. 우리는 16 엑사 바이트 크기의 파일을 가지고있을 때 몇 년 후 128 비트로 재정의 할 수 있습니다.

Windows를 사용하는 경우 GetFileSizeEx 를 사용해야합니다. 실제로는 부호있는 64 비트 정수를 사용하므로 8 개의 exabyte 파일로 문제가 발생합니다. 어리석은 Microsoft! :-)





filesize