<C Code> Binary 파일 입력 받을때 Data size 처리

peachpony777의 이미지

Binary File 입력을 받아서 fread 함수로 메모리에 저장을 할때,
Data Size가 가변적인데 이를 처리할 방법이 없을까요?

예를들어,

typedef struct _DATA
{
char header[3];
char data[20];
}DATA;

로 구조체를 설정하고 파일오픈을 한 후 fp 변수로 받은다음,

DATA sData[??];
fread (sData, sizeof(DATA), ??, fp);

로 받아올때 DATA 구조체가 몇번 반복될지 모른다면(파일마다 다르다면) 어떻게 처리해야 할까요?

코딩 경험이 부족하여 간단한것 같은 문제도 고민이네요, 좋은 방법 아시는분 답변 부탁드립니다.

peecky의 이미지

realloc()으로 필요할 때 마다 메모리 할당량을 늘리는 방법을 사용할 수 있습니다.

DATA * sData = NULL;
int i, total;
 
for (i = 0; !feof(fp); i++) {
	sData = realloc(sData, sizeof(DATA) * (i+1));
	if (!fread(sData + i, sizeof(DATA), 1, fp)) break;
}
total = i;
 
for (i = 0; i < total; i++) {
	// sData[i].header
	// sData[i].data
}
 
free(sData);

아니면 링크드 리스트를 사용하는 방법도 있습니다.

jick의 이미지

realloc 함수 자체가 느린 것은 아닙니다만, realloc은 불릴 때마다 할당된 메모리 영역을 통째로 이동해야 할 수 있습니다.

따라서 이 코드에서는 n번째에 이동해야 할 메모리의 양이 O(n)이므로 루프를 n번 돌게 되면 O(n^2)의 시간을 쓰게 됩니다.

파일에 있는 데이터의 갯수가 수천 개만 되어도 체감상 느낄 정도로 코드가 느려질 수 있습니다.

rookey94의 이미지

반드시 반복해서 읽어들여야 하는 이유가 없다면

파일을 읽어 드리기 전에
fstat으로 파일 크기(st_size)를 알아내어 할당 후 크기만큼 읽어 들이시면 됟듯 한데요.

typedef struct _DATA
{
char header[3];
char* data; // 할당한 메모리 주소
}DATA;

도움이 되시길...

unipro의 이미지

파일을 모두 읽어야 다음 단계를 처리할 수 있다면,
- 일어야 할 데이터의 크기를 사전에 계산하여 충분한 크기의 메모리를 할당받아서 사용하거나, (앞서 설명한 fstat 같은 것)
- 적절한 데이타 구조체(예를 들면, 링크드 리스트)에 DATA를 읽어들이는 방법이 있습니다. (fread에서 EOF 나올 때까지)

그런데, 왠지 DATA가 header, data로 구성된 것을 미루어보면, 각 DATA를 독립적으로 처리하도록 설계된 것처럼 보입니다.
또는 연결된 몇개의 DATA를 독립적으로 처리할 수도 있겠구요.
여튼, 이러한 경우, 처리 가능한 정도씩 읽어서 다음 단계로 전달하는 방식을 사용합니다.
여기서도 fread에서 EOF가 나올 때까지 처리하면 됩니다.

후자가 가능하다면 되도록 후자를 사용하세요.
- 메모리의 이득을 볼 수 습니다.
- 처리 과정에서 오류를 발견하면 여러가지 방식으로 읽기에 영향을 줄 수 있습니다. (읽기 중단, 읽기 보정 등)

내 블로그: http://unipro.tistory.com

yukariko의 이미지

질문의 요지와는 벗어난 답변인것 같습니다만..

구조체 변수의 값을 파일 입출력으로 받아올 때
fread (sData, sizeof(DATA), ??, fp);
이러한 방식으로 받아오는것은 그다지 좋지 못하다고 알고있는데 아닌가요?

typedef struct _DATA
{
char header[3];
char data[20];
}DATA;

위 경우에는 아키텍처나 컴파일러에 따라 sizeof(DATA)의 값이 23이 될수도 24가 될수도 있는데,
후자의 경우는 header가 실질적으로 3바이트가 아닌 4바이트가 되어
data값이 한칸씩 앞으로 밀리는 오류를 범할 수 있는것으로 알고있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.