programing

fread는 실제로 어떻게 작동합니까?

newsource 2022. 8. 25. 00:01

fread는 실제로 어떻게 작동합니까?

fread

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

는, 하는 이러한 콜은, 「이러다」입니다.fread:

char a[1000];
  1. fread(a, 1, 1000, stdin);
  2. fread(a, 1000, 1, stdin);

★★★★★★★라고 써있나요?1000번에 바이트를 표시합니까?

퍼포먼스에 차이가 있을 수도 있고 없을 수도 있습니다.의미론에는 차이가 있다.

fread(a, 1, 1000, stdin);

는 각각 길이가 1바이트인 1000개의 데이터 요소를 읽으려고 합니다.

fread(a, 1000, 1, stdin);

는 1000바이트 길이의 1개의 데이터 요소를 읽으려고 합니다.

다르다, 다르다, 다르다, 다르다, 다르다, 다르다, 다르다, 다르다.fread()바이트 수가 아니라 읽을 수 있었던 데이터 요소의 수를 반환합니다. 상태에 도달한 첫 은 읽은두 버전은 01000 바이트가 됩니다.

실제로는 1000바이트 읽기를 시도하고 실제로 읽은 바이트 수를 나타내는 하위 수준의 함수를 호출할 수 있습니다.판독치가 큰 경우는, 저레벨의 콜을 복수 발신할 가능성이 있습니다.에 의해 fread()이치노

데이터 읽기를 시도하기 전에 구현에서 읽을 데이터가 부족하다는 것을 알 수 있다면 차이가 있을 수 있습니다.예를 들어 900바이트 파일에서 읽을 경우 첫 번째 버전은 900바이트를 모두 읽고 900바이트를 반환하는 반면 두 번째 버전은 아무것도 읽을 필요가 없습니다.어느 경우든, 파일 위치 인디케이터는, 정상적으로 읽혀진 문자수, 즉 900 문자수만큼 전진한다.

그러나 일반적으로 필요한 정보에 따라 호출 방법을 선택해야 합니다.부분 판독이 아무것도 읽지 않는 것과 다를 바 없는 경우 단일 데이터 요소를 읽습니다.부분 읽기가 유용한 경우 더 작은 청크로 읽습니다.

이것이 구현 세부 사항입니다.glibc에서는 기본적으로 (Ref http://sourceware.org/git/?p=glibc.bc;a=blob;f=libio/iofread.c)와 같이 구현되어 있기 때문에 두 개의 퍼포먼스는 동일합니다.

size_t fread (void* buf, size_t size, size_t count, FILE* f)
{
    size_t bytes_requested = size * count;
    size_t bytes_read = read(f->fd, buf, bytes_requested);
    return bytes_read / size;
}

CPOSIX 규격은 완전한 크기의 오브젝트를 보증하지 않습니다.size매번 읽어야 합니다. 수 「」등).stdin 999바이트를 size == 1000C99의 7.19.8.1/2)에 대해 설명합니다.

편집: POSIX에 대한 다른 답변을 참조하십시오.

fread ®getc에에의 부부 Minix numbergetc라고 합니다.size*nmembgetc이 두 개의 에 따라 호출됩니다.둘 다fread(a, 1, 1000, stdin) ★★★★★★★★★★★★★★★★★」fread(a, 1000, 1, stdin)getc 1000=(1000*1)Times. 여기 Minix의 간단한 구현이 있습니다.

size_t fread(void *ptr, size_t size, size_t nmemb, register FILE *stream){
register char *cp = ptr;
register int c;
size_t ndone = 0;
register size_t s;

if (size)
    while ( ndone < nmemb ) {
    s = size;
    do {
        if ((c = getc(stream)) != EOF)
            *cp++ = c;
        else
            return ndone;
    } while (--s);
    ndone++;
}

return ndone;
}

명세서에 따르면, 이 둘은 실장에 의해 다르게 취급될 수 있다.

"1000" 입니다.fread(a, 1, 1000, stdin)(각각 1바이트의 1000개의 요소를 읽습니다)는 EOF까지 모든 바이트를 복사합니다. 편,, of of의 fread(a, 1000, 1, stdin)요소 에되어 있습니다.a데이터가 부족하여 '첫 번째' (및 유일한) 1000바이트 요소의 읽기를 완료할 수 없기 때문에 지정되지 않았습니다.

물론 일부 구현에서는 여전히 '부분' 요소를 필요한 만큼 바이트 수로 복사할 수 있습니다.

여기서 답변을 명확히 하고 싶습니다.fread는 버퍼링된 IO를 수행합니다.fread에서 사용되는 실제 읽기 블록 크기는 사용되는 C 구현에 따라 결정됩니다.

모든 최신 C 라이브러리는 다음 2개의 콜에서 동일한 성능을 발휘합니다.

fread(a, 1, 1000, file);
fread(a, 1000, 1, file);

예를 들어 다음과 같습니다.

for (int i=0; i<1000; i++)
  a[i] = fgetc(file)

fgetc는 표준 c 라이브러리로의 콜이 많아지고 경우에 따라서는 디스크에서 추가 검색을 실행해야 하기 때문에 디스크 접근패턴이 같아집니다.

두 가지 형태의 fread의 차이점을 다시 살펴봅시다.전자는 실제 읽은 바이트 수를 반환합니다.파일 크기가 1000 미만일 경우 후자는 0을 반환하고 그렇지 않을 경우 1을 반환합니다.두 경우 모두 버퍼는 동일한 데이터, 즉 최대 1000바이트의 파일 내용으로 채워집니다.

일반적으로 두 번째 파라미터(사이즈)를 1로 설정하여 읽기 바이트 수를 얻는 것이 좋습니다.

퍼포먼스의 차이는 없을지도 모르지만, 이러한 콜은 동일하지 않습니다.

  • fread는 판독된 요소의 수를 반환하기 때문에 이들 콜은 다른 값을 반환합니다.
  • 요소를 완전히 읽을 수 없는 경우 값은 미확정입니다.

오류가 발생하면 스트림에 대한 파일 위치 표시기의 결과 값이 정해지지 않습니다.일부 요소를 읽을 경우, 그 값은 불확정입니다.(ISO/IEC 9899:TC2 7.19.8.1)

glibc 실장에서는 큰 차이는 없습니다.이 실장에서는 요소 사이즈에 요소의 수를 곱하여 읽을 바이트 수를 결정하고 최종적으로 읽은 양을 멤버사이즈로 나눕니다.그러나 요소 크기를 1로 지정하는 버전에서는 항상 올바른 읽기 바이트 수를 알 수 있습니다.그러나 특정 크기의 전체 읽기 요소에만 관심이 있는 경우 다른 양식을 사용하면 나눗셈을 수행할 필요가 없습니다.

http://pubs.opengroup.org/onlinepubs/000095399/functions/fread.html에서 한 문장 더 볼 수 있습니다.

fread() 함수는 ptr에 의해 지시된 어레이를 스트림에 의해 지시된 스트림에서 바이트 단위로 크기가 지정된 니텀 요소까지 읽어 들여야 합니다.객체에 대해 fgetc() 함수에 대한 크기 호출이 이루어지며, 결과는 읽기 순서대로 객체에 정확히 오버레이되는 부호 없는 문자 배열로 저장됩니다.

두 경우 모두 fgetc()에 의해 inshort에 액세스 됩니다!

언급URL : https://stackoverflow.com/questions/8589425/how-does-fread-really-work