C # .NET으로 작성한 응용 프로그램에 대한 독점 파일 형식을 작성하여 저장 정보를 저장하고 아마도 줄 프로젝트 자산을 저장하고 있습니다. 어떤 식 으로든이 작업을 수행하는 방법에 대한 표준이 있습니까? 나는 단순히 Serialize
객체를 바이너리로 옮기고 파일을 구문 분석하는 방법을 알려주는 헤더를 만들었습니다. 이것은 나쁜 접근입니까?
C # .NET으로 작성한 응용 프로그램에 대한 독점 파일 형식을 작성하여 저장 정보를 저장하고 아마도 줄 프로젝트 자산을 저장하고 있습니다. 어떤 식 으로든이 작업을 수행하는 방법에 대한 표준이 있습니까? 나는 단순히 Serialize
객체를 바이너리로 옮기고 파일을 구문 분석하는 방법을 알려주는 헤더를 만들었습니다. 이것은 나쁜 접근입니까?
답변:
가장 간단한 방법은 아마도 XMLSerializer
클래스를 사용하여 구조를 XML로 직렬화하는 것입니다 . 별도의 헤더 및 본문 구조를 만들 필요는 없지만 모든 자산을 XML로 직렬화하십시오. 이를 통해 자신의 프로그램 외부에서 파일 구조를 쉽게 검사 / 편집 할 수 있으며 쉽게 관리 할 수 있습니다.
그러나 파일 구조가 실제로 복잡하고 유형이 다른 여러 자산이 포함되어 전체 구조를 XML로 직렬화하는 것이 너무 번거로운 경우 Packaging
C # 의 라이브러리를 사용하여 각 자산을 개별적으로 직렬화하고 단일 패키지로 컴파일하는 것을 볼 수 있습니다 . 이것은 본질적으로 .docx, .xslx, .pptx 및 기타 오피스 파일 형식이 구성되는 방식입니다.
protobuf-net
내 데이터를 직렬화하는 데 사용하고 있으며 그 기능이 훌륭합니다. 그러나 조각을 개별적으로 직렬화해야하므로 패키징 라이브러리에 대해 이야기하는 것이 필요한 것 같습니다.
많은 파일 형식을 구문 분석 해야하는 사람으로부터 다른 관점에서 대부분에 대해 의견이 있습니다.
다른 형식의 사람들의 파일 형식 탐지기가 사용자의 것으로 잘못 식별하지 않도록 마법 번호를 매우 고유하게 만드십시오. 이진수를 사용하는 경우, 이진수 형식의 시작시 매직 넘버에 8 또는 16 개의 무작위로 생성 된 바이트를 할당하십시오. XML을 사용하는 경우 다른 사람과 충돌 할 수 없도록 도메인에 적절한 네임 스페이스를 할당하십시오. JSON을 사용한다면 신의 도움이됩니다. 어쩌면 누군가가 그 형식의 혐오에 대한 해결책을 지금 쯤 정렬했을 수도 있습니다.
이전 버전과의 호환성을 계획하십시오. 최신 버전의 소프트웨어에서 차이점을 처리 할 수 있도록 형식의 버전 번호를 저장하십시오.
파일이 크거나 어떤 이유로 사람들이 건너 뛸 수있는 섹션이있는 경우이를 수행 할 수있는 좋은 방법이 있는지 확인하십시오. XML, JSON 및 대부분의 다른 텍스트 형식은 독자가 시작과 끝 요소 사이에 상관없이 모든 데이터를 구문 분석하도록 강요하기 때문에 특히 끔찍합니다. EBML은 요소의 길이를 저장하므로 끝까지 건너 뛸 수 있기 때문에 다소 우수합니다. 사용자 정의 이진 형식을 만드는 경우 청크 식별자와 길이를 헤더에 첫 번째로 저장하는 독자적인 디자인이 있으며 독자는 전체 청크를 건너 뛸 수 있습니다.
모든 문자열을 UTF-8로 저장하십시오.
장기 확장 성을 염려한다면 모든 정수를 가변 길이 형식으로 저장하십시오.
체크섬은 혼란스러운 결과를 초래할 수있는 파일 섹션으로 이동할 가능성없이 판독기가 유효하지 않은 데이터를 즉시 중단 할 수 있기 때문에 좋습니다.
글쎄, 당신이 묘사하는 것이 매우 나쁜 접근법 일 수 있습니다. 이것은 '직렬화'라고 말할 때 언어 / 프레임 워크의 기능을 사용하여 단순히 객체를 가져 와서 일종의 이진 스트림으로 직접 출력한다고 가정합니다. 문제는 수년에 걸친 수업 구조 변화입니다. 모든 클래스가 새로운 클래스로 변경되면 이전 버전의 앱에서 만든 파일을 다시로드 할 수 있습니까?
파일 형식의 장기적인 안정성을 위해 지금 소매를 약간 롤업하고 클래스 내에서 '직렬화'/ '스트리밍'메소드를 작성하는 것이 좋습니다. 즉, 값을 스트림에 쓰는 것을 수동으로 처리합니다. 형식 버전을 설명하는 헤더를 작성한 다음 원하는 순서대로 저장하려는 데이터를 작성하십시오. 읽기 측면에서 파일 형식의 다른 버전을 처리하는 것이 훨씬 쉬워집니다.
물론 다른 옵션은 XML 또는 JSON입니다. 바이너리 무거운 콘텐츠에는 반드시 필요한 것이 아니라 단순하고 사람이 읽을 수있는 것입니다.
또한 것이다 사랑 나 자신보다는 년 더 많은 경험을 가진 사람에서이 질문에 대한 답변을 듣고.
나는 개인적으로 작업을 위해 여러 파일 형식을 구현했으며 XML 파일 형식을 사용하기로 옮겼습니다. 내가 상호 작용하는 내 요구 사항과 하드웨어는 항상 변경되며 앞으로 형식에 추가해야 할 내용은 없습니다. XML의 주요 장점 중 하나는 반 구조적 이라는 점입니다 . 이러한 이유로 나는 일반적으로 .NET이 정확한 형식을 요구한다고 믿기 때문에 .NET이 제공하는 자동 XML 직렬화를 피합니다.
저의 목표는 미래에 새로운 요소와 속성을 추가하고 가능할 때마다 태그 순서가 중요하지 않게하는 XML 형식을 만드는 것이 었습니다. 전체 파일을 메모리에로드 할 수 있다고 확신한다면 XPATH 를 사용하는 것이 좋습니다.
특히 큰 파일을 처리하거나 다른 이유로 파일을 한 번에 모두로드 할 수없는 경우 XmlStreamReader를 사용하여 알려진 요소를 검색 한 후 ReadSubtree를 사용하여 해당 요소로 다시 돌아가서 다시 스캔하는 경우가 있습니다.
BinaryFormatter
.