null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
바이너리 파일 (Binary File)
#c
#c-lang
#intermediate
#file-io
#binary-file
@devpc
|
2026-03-29 12:57:39
|
GET /api/v1/nodes/54?nv=2
History:
v2 (2026-03-29) (Latest)
v1 (2026-03-29)
0
Views
5
Calls
# 바이너리 파일 (Binary File) ## 텍스트 vs 바이너리 | 구분 | 텍스트 모드 | 바이너리 모드 | |------|------------|-------------| | 데이터 | 사람이 읽을 수 있는 문자 | 메모리 그대로 (raw bytes) | | 개행 처리 | OS마다 변환 (Windows: `\r\n`) | 변환 없음 | | 속도 | 파싱 필요, 상대적으로 느림 | 빠름 | | 파일 크기 | 숫자 → 문자열 변환으로 클 수 있음 | 타입 크기 그대로 | | 모드 | `"r"`, `"w"` | `"rb"`, `"wb"` | --- ## fwrite — 바이너리 쓰기 ```c size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); ``` - `ptr`이 가리키는 메모리에서 `size * nmemb` 바이트를 파일에 씁니다. - 반환값: 성공적으로 쓴 원소 수 ```c #include <stdio.h> int main(void) { int numbers[5] = {10, 20, 30, 40, 50}; FILE *fp = fopen("numbers.bin", "wb"); if (!fp) { perror("fopen"); return 1; } size_t written = fwrite(numbers, sizeof(int), 5, fp); printf("쓴 원소 수: %zu\n", written); // 5 fclose(fp); return 0; } ``` --- ## fread — 바이너리 읽기 ```c size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); ``` - 파일에서 `size * nmemb` 바이트를 읽어 `ptr`에 저장합니다. - 반환값: 성공적으로 읽은 원소 수 ```c int loaded[5]; FILE *fp = fopen("numbers.bin", "rb"); if (!fp) { perror("fopen"); return 1; } size_t n = fread(loaded, sizeof(int), 5, fp); printf("읽은 원소 수: %zu\n", n); for (size_t i = 0; i < n; i++) { printf("%d ", loaded[i]); // 10 20 30 40 50 } printf("\n"); fclose(fp); ``` --- ## 구조체 직렬화 (Struct Serialization) 구조체를 통째로 파일에 저장하고 불러올 수 있습니다. ```c #include <stdio.h> #include <string.h> typedef struct { char name[50]; int age; float gpa; } Student; // 구조체 배열을 바이너리 파일에 저장 void save_students(const char *path, const Student *arr, int n) { FILE *fp = fopen(path, "wb"); if (!fp) { perror("fopen"); return; } fwrite(&n, sizeof(int), 1, fp); // 원소 수 먼저 저장 fwrite(arr, sizeof(Student), n, fp); // 구조체 배열 저장 fclose(fp); } // 바이너리 파일에서 구조체 배열 불러오기 int load_students(const char *path, Student *arr, int max) { FILE *fp = fopen(path, "rb"); if (!fp) { perror("fopen"); return 0; } int n = 0; fread(&n, sizeof(int), 1, fp); // 원소 수 읽기 if (n > max) n = max; fread(arr, sizeof(Student), n, fp); // 구조체 배열 읽기 fclose(fp); return n; } int main(void) { Student students[] = { {"Alice", 20, 3.8f}, {"Bob", 22, 3.5f}, {"Charlie", 21, 3.2f}, }; save_students("students.bin", students, 3); Student loaded[10]; int n = load_students("students.bin", loaded, 10); for (int i = 0; i < n; i++) { printf("%-10s %3d %.1f\n", loaded[i].name, loaded[i].age, loaded[i].gpa); } return 0; } ``` --- ## 파일 위치 제어 ```c // ftell — 현재 파일 위치(오프셋) 반환 long pos = ftell(fp); // fseek — 파일 위치 이동 fseek(fp, 0, SEEK_SET); // 파일 처음으로 fseek(fp, 0, SEEK_END); // 파일 끝으로 fseek(fp, -10, SEEK_CUR); // 현재 위치에서 10바이트 뒤로 // 파일 크기 구하기 fseek(fp, 0, SEEK_END); long size = ftell(fp); fseek(fp, 0, SEEK_SET); // 처음으로 되돌리기 // rewind — 파일 처음으로 (fseek(fp, 0, SEEK_SET)과 동일) rewind(fp); ``` ### 특정 인덱스의 구조체만 읽기 ```c // i번째 Student 직접 접근 long offset = sizeof(int) + sizeof(Student) * i; // 앞에 n(int)가 저장됨 fseek(fp, offset, SEEK_SET); Student s; fread(&s, sizeof(Student), 1, fp); ``` --- ## 바이너리 파일 주의사항 | 주의 사항 | 내용 | |-----------|------| | 패딩 의존 | 구조체 패딩이 컴파일러/플랫폼마다 다를 수 있음 | | 엔디안 | 다른 아키텍처에서는 바이트 순서가 다를 수 있음 | | 이식성 | 텍스트 파일보다 이식성이 낮음 | | 용도 | 성능이 중요하거나 같은 플랫폼 내 저장 시 사용 | --- ## 정리 | 함수 | 역할 | |------|------| | `fwrite(ptr, size, n, fp)` | `n`개의 `size`바이트 원소 쓰기 | | `fread(ptr, size, n, fp)` | `n`개의 `size`바이트 원소 읽기 | | `fseek(fp, offset, whence)` | 파일 커서 위치 이동 | | `ftell(fp)` | 현재 커서 위치(바이트) 반환 | | `rewind(fp)` | 커서를 파일 처음으로 이동 | ---
// COMMENTS
ON THIS PAGE