TEXT 및 바이너리 데이터가 혼합되어 있는 파일에서의 offset 구

kernelbomb의 이미지

안녕하세요?

다름이 아니오라 특정 파일이 존재하는데

헤더부분은 text로 데이터를 입력했고,

body부분엔 바이너리 데이터를 읽어서 입력해놨습니다.

또한 body 데이터가 끝나면 다시 text로 헤더를 입력시켰습니다.

역시 text 밑에는 바이너리 데이터가 들어가구요.

간단하게 파일을 열고, 바이너리 데이터에 대한 헤더를 찾아서 파일의

offset을 알아내고 offset에서 부터 헤더에 있는 데이터 싸이즈만큼

읽어서 다른 파일로 쓰게 하는 프로그램입니다.

Quote:
----------------------------
text data(헤더내용)
----------------------------
bin data
----------------------------
text data(헤더내용)
----------------------------
bin data
----------------------------

* 헤더 내용엔 bin data의 크기가 저장되어 있습니다.

위와 같은 형식이 되는데요.

목적은 하나의 파일에 바이너리 파일을 여러게 집어 넣고 관리하는것을

만들려고 합니다.

이 파일을 읽어서(fopen(filename, "rb")) 파일 싸이즈만큼

메모리를 할당하고 할당한 메모리에 파일 데이터를 모두 옮겨놓고,

두번째 text_data(헤더내용)를 찾기 위해 strstr();을 썼는데요

첫번째 헤더는 잘 찾아서 바이너리 데이터를 만들어 주는데,

두번째는 찾지를 못하네요.

pdst = strstr(buffer, "BIN:test.dat:2334");
result = pdst - buffer + 1;   /* offset을 알아낸다 */

buffer는 메모리를 할당해서 파일 내용을 모두 저장시킨 것입니다.

아마 첫번째 바이너리 데이터부분에 '\0'인 데이터가 있어서 두번째

헤더까지 못찾아 가는것 같은데요. 이럴땐 어떻게 비교를 해서 파일의

offset을 알아내야 하는지요?

이런 방법이 별로라면 더 좋은 방법이 있으면 좀 알려주세요~~

ssik425의 이미지

우선 참 복잡하게 하시네요 ^^;;

그냥 간단하게 base64로 인코딩해서 저장을 하시면

strstr을 쓰는데 문제가 없지 않을까요?

용량이 너무 커질라나 ㅠ.ㅠ

개발자들의 궁극적 비전은 ?

nachnine의 이미지

base64는 파일의 크기가 1/3 정도 커지는 관계로

별로 좋지 않습니다.

헤더부분에 다음 헤더의 위치를 같이 기록하십시오.

아니면 다음헤더의 위치가 어디인지

( 편법을 사용하지 않으면 ) 보장할수 없습니다.

ssik425의 이미지

nachnine 님이 헤더 위치를 저장한다고 하셨는데

정말 좋은 아이디어 인것 같네요..

그런데, 이파일을 만약 수정한다면 조금 머리 아파 지지 않을 까요..

하나의 바이너리 파일을 수정하면 나머지 파일에 대한

위치를 다시 찾아서 저장해야 하는 번거로움이 있지 않을까요?

개발자들의 궁극적 비전은 ?

hackexpert의 이미지

파일 헤더 안에 파일 사이즈를 적어주면 됩니다..
바로 해당 위치로는 찾아갈 수 없겠지만..
중간중간 바이너리 부분은 건너뛸 수 있겠죠..

음.. 그리고 http에서
multipart/form-data 형식을 한번 보시면 도움이 될 것 같습니다.

계속해서 파일을 추가해야 한다면
boundary를 변경해야 할 수도 있기때문에
그대로는 사용 못하겠지만..

insup2의 이미지

결론부터 말하면,
binary로 모두 저장하세요.

원래는 file format에 따라서 fopen을 다르게 해야 합니다.
(fopen 옵션에 'r', 또는 'rb')
그래야 fseek가 제대로 찾아갈 수 있습니다.

님과 같은 경우는 text, binary를 혼용하고 있는데,
text문자열도 binary로 저장해도 별 문제는 없습니다.
어짜피 vi 같은 text editor로 헤더를 열어 볼게 아니고,
프로그램 상에서 헤더를 읽기 때문에,
binary로 통일해서 저장해도 문제 없습니다.

insup2의 이미지

질문을 다시 읽다 보니까...
파일 사이즈 만큼 메모리 할당 후에 strstr로 문자열을 찾아가는데...
제 경험으로는...
파일에 있는 데이터를 다시 메모리에 올릴 필요는 없을 듯 합니다...
파일은... 아주 훌륭한 대용량의 메모리입니다...
파일에서 바로 탐색하시는게...
시스템 성능면에서 효과적입니다...

fseek(), getc() 를 잘 조합하면...
아주 훌륭한 탐색 기능이 됩니다...

불량청년의 이미지

제가 이해하기로는 역시 쓸 때 wb로 파일을 쓰고

해당 파일에서 text에 해당하는 헤더를 찾아서

offset을 알아낸후 fseek();로 이동하여 그 바이너리

데이터를 새로운 파일에 쓴다는 얘기 같은데요.

문제는 바이너리 데이터에 대한 헤더를 어떻게 찾는냐

하는 것이겠죠.

strstr은 문자열 연산 함수이기 때문에 바이너리 데이터에

'널'이 있다면 연산을 종료하겠죠. 즉, 그렇게 하면 안되고

한바이트씩 읽어 들여 검사해야 할것 같네요.

또한, 위에 분이 말씀하신 파일에서 직접 읽어 처리하는것은

음... 버퍼링에 의한 파일 읽기라면 상관이 없겠지만, 제가

말한 한바이트씩 읽어 처리해야 하는 상황이라면 파일 싸이즈

만큼 시스템콜을 호출해야 함으로 비용적인면이 상당히 클것으로

생각되고요, 일단, 버퍼링으로 파일을 읽어 메모리에 저장하고

한바이트씩 비교해서 파일헤더를 찾는것이 효율적일것 같습니다.

또한 스트링 처리 함수는 사용하지 마시고 메모리 관련 함수를

사용하셔야 합니다. 그럼...

H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!

shpark05의 이미지

typedef struct _mm {
unsigned char data_buff[25];
unsigned long data_size;
} mm;

// 아래 기준 입니다.
// pdst = strstr(buffer, "BIN:test.dat:2334");

BIN:test.data 등의 데이타는 buff 에 넣으시고 ,
사이즈는 data_size 에 넣으시기 바랍니다.

물론, wb 로 저장하시면 될 듯 합니다.

그냥, 표준 입출력 하신다고 생각하면,

처음에는 fwrite 로 위 구조체로 저장 다음번 저장은
그냥, buffer 을 저장 하시 면 될 듯 합니다.

읽을때는, 위의 정보가 있으니,.... 괜찮을듯...

그런데, 문제는 파일에 손상이 있을때 복구가 힘들듯... ^^;

만약, 뒤에 데이타 최대 사이즈를 알게 되신다면,

typedef struct _mm {
unsigned char data_buff[25];
unsigned long data_size;
unsigned char mydata[MAX_SIZE];
} mm;

이렇게 읽어 보시면 어떨까요 ??

물론, 같은 포멧의 파일을 읽어 내기나 쓰기 할때, MAX_SIZE가
변경되면 않될 것 같군요.

좋은 결과 있으시기를....

추신 : 더 좋은 방법은 두개의 내용을 다른 파일로 분리하세요.

ㅡ,.ㅡ;;의 이미지

머.. 어렵게 생각하시는데..

생각하기에따라 간단한겁니다

테스트와 바이터리가 같이 있는파일이라구요?? 그렇다면 그건 바이너리파일이죠..

헤더는 고정길이이며 데이터는 가변길이라면 헤더에 데이터의 길이가 들어가야함은 김치담글때 고추가루 들어가는거나 마찬가지고.
읽고저장은 struct + void * 조합형태로 하시면되죠..

종종보는건데 대기업의 큰업무에도 보면 기본을 무시한 Format으로 인하여
시스템이 굉장히 비효율적이고 둔하며 절차가 복잡해진경우를 종종봅니다.
설계자가 60년대 고전적인 방법을 고수한다든지 어쨋거나 현제 프로그램 한번제대로 안짜보고 설계하는데서 생긴 문제가 아닌가 합니다..


----------------------------------------------------------------------------

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.