파일 형식을 만드는 적절한 방법이 있습니까?


12

C # .NET으로 작성한 응용 프로그램에 대한 독점 파일 형식을 작성하여 저장 정보를 저장하고 아마도 줄 프로젝트 자산을 저장하고 있습니다. 어떤 식 으로든이 작업을 수행하는 방법에 대한 표준이 있습니까? 나는 단순히 Serialize객체를 바이너리로 옮기고 파일을 구문 분석하는 방법을 알려주는 헤더를 만들었습니다. 이것은 나쁜 접근입니까?


2
나는 피할 것이다 BinaryFormatter.
코드 InChaos

3
어떤 답변을 선택하든 항상 형식에 버전 번호를 포함하십시오! 귀하의 질문에 따르면 이미 변경 될 수 있으며 버전 번호를 사용하면 백 워즈 호환이 가능해야합니다.
Jan Doggen

형식을 올바르게 문서화하는 것을 잊지 마십시오
Basile Starynkevitch

답변:


11

가장 간단한 방법은 아마도 XMLSerializer클래스를 사용하여 구조를 XML로 직렬화하는 것입니다 . 별도의 헤더 및 본문 구조를 만들 필요는 없지만 모든 자산을 XML로 직렬화하십시오. 이를 통해 자신의 프로그램 외부에서 파일 구조를 쉽게 검사 / 편집 할 수 있으며 쉽게 관리 할 수 ​​있습니다.

그러나 파일 구조가 실제로 복잡하고 유형이 다른 여러 자산이 포함되어 전체 구조를 XML로 직렬화하는 것이 너무 번거로운 경우 PackagingC # 의 라이브러리를 사용하여 각 자산을 개별적으로 직렬화하고 단일 패키지로 컴파일하는 것을 볼 수 있습니다 . 이것은 본질적으로 .docx, .xslx, .pptx 및 기타 오피스 파일 형식이 구성되는 방식입니다.


예, 내 프로젝트는 그보다 훨씬 복잡하지만 라이센스가있는 필드의 필드에 배포 할 수 있기 때문에 사용자가 읽을 수 없게 만들려고합니다. 나는 현재 protobuf-net내 데이터를 직렬화하는 데 사용하고 있으며 그 기능이 훌륭합니다. 그러나 조각을 개별적으로 직렬화해야하므로 패키징 라이브러리에 대해 이야기하는 것이 필요한 것 같습니다.
corylulu

7
XML이 아닌 친애하는 하나님
James

2
@James yeah XML은 물론 단점이 있습니다. 같은 이유로 대부분의 경우 패키징과 XML을 선호합니다. 1. 기존 프레임 워크이므로 적은 노력이 필요합니다. 2. 널리 채택 된 표준이기 때문에 다른 시스템에서 쉽게 지원할 수 있습니다. 3. 사람이 결과 파일을 검사하여 직렬화 프로세스를 쉽게 확인할 수 있습니다.
pswg

XML에는 장점이 있지만 XML serializer를 사용하지 않는 장점 때문입니다. XML이 특정 형식이어야한다고 생각합니다. XML은 반 구조화 된 형식으로, 시간이 지남에 따라 파일 형식이 변경 되어도 이전 버전과 이전 버전 간에도 호환됩니다. 과거에는 주문에 대해 가정하지 않거나 앞으로 알지 못하는 태그가 없다는 것을주의하면서 자체 XML 구문 분석을 작성했습니다. 전체 XML 파일을로드 할 수 있으면 XPATH가 제대로 작동 할 것입니다. 그렇지 않으면 좀 더 복잡한 스트림 파싱으로 왼쪽
Alan


7

많은 파일 형식을 구문 분석 해야하는 사람으로부터 다른 관점에서 대부분에 대해 의견이 있습니다.

  • 다른 형식의 사람들의 파일 형식 탐지기가 사용자의 것으로 잘못 식별하지 않도록 마법 번호를 매우 고유하게 만드십시오. 이진수를 사용하는 경우, 이진수 형식의 시작시 매직 넘버에 8 또는 16 개의 무작위로 생성 된 바이트를 할당하십시오. XML을 사용하는 경우 다른 사람과 충돌 할 수 없도록 도메인에 적절한 네임 스페이스를 할당하십시오. JSON을 사용한다면 신의 도움이됩니다. 어쩌면 누군가가 그 형식의 혐오에 대한 해결책을 지금 쯤 정렬했을 수도 있습니다.

  • 이전 버전과의 호환성을 계획하십시오. 최신 버전의 소프트웨어에서 차이점을 처리 할 수 ​​있도록 형식의 버전 번호를 저장하십시오.

  • 파일이 크거나 어떤 이유로 사람들이 건너 뛸 수있는 섹션이있는 경우이를 수행 할 수있는 좋은 방법이 있는지 확인하십시오. XML, JSON 및 대부분의 다른 텍스트 형식은 독자가 시작과 끝 요소 사이에 상관없이 모든 데이터를 구문 분석하도록 강요하기 때문에 특히 끔찍합니다. EBML은 요소의 길이를 저장하므로 끝까지 건너 뛸 수 있기 때문에 다소 우수합니다. 사용자 정의 이진 형식을 만드는 경우 청크 식별자와 길이를 헤더에 첫 번째로 저장하는 독자적인 디자인이 있으며 독자는 전체 청크를 건너 뛸 수 있습니다.

  • 모든 문자열을 UTF-8로 저장하십시오.

  • 장기 확장 성을 염려한다면 모든 정수를 가변 길이 형식으로 저장하십시오.

  • 체크섬은 혼란스러운 결과를 초래할 수있는 파일 섹션으로 이동할 가능성없이 판독기가 유효하지 않은 데이터를 즉시 중단 할 수 있기 때문에 좋습니다.


내가 json이 형식의 혐오라고 생각하는 유일한 사람이 아니라는 것을 깨닫게 해준 +1.
RubberDuck 2016 년

왜 json을 싫어합니까? 알려진 문자열을 알려진 위치에 넣어 형식을 식별하십시오. 문제 해결됨.
Esben Skov Pedersen

완벽하지는 않지만 Javascript와 완벽하게 작동하며 XML보다 파싱 속도가 빠르며 크기는 작으며 여전히 사람이 읽을 수 있습니다.
corylulu

1
"JSON을 싫어하는 이유는 무엇입니까?" 사람이 읽을 수있는 주석, 유니 코드 크랩 이스케이프 및 공백이 포함되어 있지 않더라도 키를 인용해야하는 이상한 구문은 지원되지 않습니다. 게다가 이름 공간에 대해 아무도 생각하지 않았기 때문에 일을 확장 할 수없는 일반적인 능력 .. 당신이 그 이름을 결정할 때, 당신은 XML을 처음보다 더 나빠 보이는 것으로 끝납니다. 괄호?
Trejkaz 2016 년

예, 그러나 프로그래밍과 관련된 모든 작업과 마찬가지로 작업에 적합한 도구를 사용하십시오. XML이 JSON보다 좋고 그 반대의 경우도 있습니다.
corylulu

4

글쎄, 당신이 묘사하는 것이 매우 나쁜 접근법 일 수 있습니다. 이것은 '직렬화'라고 말할 때 언어 / 프레임 워크의 기능을 사용하여 단순히 객체를 가져 와서 일종의 이진 스트림으로 직접 출력한다고 가정합니다. 문제는 수년에 걸친 수업 구조 변화입니다. 모든 클래스가 새로운 클래스로 변경되면 이전 버전의 앱에서 만든 파일을 다시로드 할 수 있습니까?

파일 형식의 장기적인 안정성을 위해 지금 소매를 약간 롤업하고 클래스 내에서 '직렬화'/ '스트리밍'메소드를 작성하는 것이 좋습니다. 즉, 값을 스트림에 쓰는 것을 수동으로 처리합니다. 형식 버전을 설명하는 헤더를 작성한 다음 원하는 순서대로 저장하려는 데이터를 작성하십시오. 읽기 측면에서 파일 형식의 다른 버전을 처리하는 것이 훨씬 쉬워집니다.

물론 다른 옵션은 XML 또는 JSON입니다. 바이너리 무거운 콘텐츠에는 반드시 필요한 것이 아니라 단순하고 사람이 읽을 수있는 것입니다.


확장 가능한 protobuf-net ( code.google.com/p/protobuf-net )을 사용하여 직렬화하고 있습니다. 그러나 귀하의 요점은 유효하지만, 이것에 면역되는 파일 형식의 방법이라고 생각하지 않습니다.
corylulu

그렇습니다 ... 그래서 때로는 때로는 손이 더러워지고 데이터가 수동으로 작성되고로드되는 순서를 처리해야한다고 말합니다.
GrandmasterB

내가 만들고있는 응용 프로그램은 역동적이며 너무 많은 가치가 있습니다.
corylulu

1
응용 프로그램이 복잡할수록 파일 형식을 매우 세밀하게 제어하는 ​​것이 중요합니다. 각 클래스가 자체 스트리밍 가능한 출력을 가져서는 안된다고 말하는 것은 아닙니다. 단, 각 클래스에 대해 제어해야한다는 것을 명심하십시오. 그런 다음 해당 루틴을 호출하십시오.
GrandmasterB

예, 레거시 버전을 최신 버전으로 업그레이드하는 방법이 있으며 수업 준비 방법이 매우 명확합니다. 나는 그것에 대해 지나치게 걱정하지 않지만 그것이 중요하다는 데 동의합니다. 나는 거의 1 년 동안이 작업을 해 왔으므로 그것이 어떻게 작동하는지에 대한 명확한 시야를 가지고 있습니다.
corylulu

1

또한 것이다 사랑 나 자신보다는 년 더 많은 경험을 가진 사람에서이 질문에 대한 답변을 듣고.

나는 개인적으로 작업을 위해 여러 파일 형식을 구현했으며 XML 파일 형식을 사용하기로 옮겼습니다. 내가 상호 작용하는 내 요구 사항과 하드웨어는 항상 변경되며 앞으로 형식에 추가해야 할 내용은 없습니다. XML의 주요 장점 중 하나는 반 구조적 이라는 점입니다 . 이러한 이유로 나는 일반적으로 .NET이 정확한 형식을 요구한다고 믿기 때문에 .NET이 제공하는 자동 XML 직렬화를 피합니다.

저의 목표는 미래에 새로운 요소와 속성을 추가하고 가능할 때마다 태그 순서가 중요하지 않게하는 XML 형식을 만드는 것이 었습니다. 전체 파일을 메모리에로드 할 수 있다고 확신한다면 XPATH 를 사용하는 것이 좋습니다.

특히 큰 파일을 처리하거나 다른 이유로 파일을 한 번에 모두로드 할 수없는 경우 XmlStreamReader를 사용하여 알려진 요소를 검색 한 후 ReadSubtree를 사용하여 해당 요소로 다시 돌아가서 다시 스캔하는 경우가 있습니다.


이 답변은 Q에 관한 것이 아니며,이 사이트는 토론 게시판이 아니라 비추 론적 인 Q & A를위한 것입니다. 질문자의 접근 방식이 왜 좋거나 좋지 않은지에 대한 제안을 주장하는 데 사용할 수있는 몇 가지 유효한 지적 사항이 있지만 그다지 집중되어 있지는 않습니다. 질문에 대한 답변에 조금 더 집중하십시오, 감사합니다!
Jimmy Hoffa

@JimmyHoffa 내 답변도 OP의 질문을 뒷받침했지만 XML 반 구조적 접근 방식을 제안하고 있음을 분명히 알았습니다. 그러나 의미가 무엇인지 알 수 있습니다.
Alan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.