Có một cách thích hợp để tạo một định dạng tập tin?


12

Tôi đang xây dựng một định dạng tệp độc quyền cho một ứng dụng mà tôi đã viết bằng C # .NET để lưu trữ thông tin và có lẽ xuống tài sản dự án. Có một tiêu chuẩn về cách làm điều này theo bất kỳ cách nào? Tôi chỉ đơn giản là đi đến Serializecác đối tượng của mình thành nhị phân và tạo một tiêu đề sẽ cho tôi biết cách phân tích tệp. Đây có phải là một cách tiếp cận xấu?


2
Tôi sẽ tránh BinaryFormatter.
CodeInChaos

3
Dù bạn chọn cách tiếp cận nào (từ câu trả lời), hãy luôn bao gồm số phiên bản trong định dạng! Câu hỏi của bạn đã gợi ý rằng nó có thể thay đổi và số phiên bản sẽ giúp bạn tiết kiệm rất nhiều nỗ lực nếu bạn phải tương thích backwarsd.
Jan Doggen

Đừng quên ghi lại đúng định dạng
Basile Starynkevitch

Câu trả lời:


11

Phương thức đơn giản nhất có lẽ là tuần tự hóa cấu trúc của bạn thành XML bằng cách sử dụng XMLSerializerlớp. Bạn có thể không cần phải tạo một cấu trúc cơ thể và tiêu đề riêng biệt - nhưng tuần tự hóa tất cả các tài sản thành XML. Điều này cho phép bạn dễ dàng kiểm tra / chỉnh sửa cấu trúc tệp của mình bên ngoài chương trình của riêng bạn và có thể dễ dàng quản lý.

Tuy nhiên, nếu cấu trúc tệp của bạn thực sự phức tạp, chứa nhiều tài sản thuộc các loại khác nhau, như vậy việc tuần tự hóa toàn bộ cấu trúc thành XML là quá nặng nề, bạn có thể xem xét tuần tự hóa từng tài sản riêng lẻ và biên dịch chúng thành một gói bằng Packagingthư viện trong C # . Đây thực chất là cách .docx, .xslx, .pptx và các định dạng tệp văn phòng khác được xây dựng.


Vâng, dự án của tôi phức tạp hơn nhiều so với điều đó, nhưng tôi cũng đang cố gắng làm cho nó ít người dùng hơn vì chúng tôi có thể triển khai chúng trong một lĩnh vực trong bối cảnh được cấp phép. Tôi hiện đang sử dụng protobuf-netđể tuần tự hóa dữ liệu của mình và điều đó rất hiệu quả. Nhưng tôi phải nối tiếp các phần riêng biệt, vì vậy những gì bạn đang nói với thư viện Bao bì nghe có vẻ giống như những gì tôi cần.
corylulu

7
Chúa ơi không phải XML
James

2
@James yeah XML có nhược điểm của nó, tất nhiên. Tôi ủng hộ việc đóng gói và XML trong hầu hết các trường hợp vì cùng một lý do: 1. đó là một khung có sẵn, do đó đòi hỏi nỗ lực thấp. 2. Thật dễ dàng để các hệ thống khác hỗ trợ, vì đó là một tiêu chuẩn được chấp nhận rộng rãi. 3. Thật dễ dàng để con người kiểm tra tệp kết quả để xác minh quá trình tuần tự hóa.
pswg

XML có những lợi thế, nhưng chính vì những ưu điểm đó mà tôi không thích sử dụng trình tuần tự hóa XML. Tôi tin rằng nó đòi hỏi XML phải ở một định dạng cụ thể. XML là một định dạng bán cấu trúc, cho phép định dạng tệp của tôi thay đổi theo thời gian và vẫn tương thích ngược và thậm chí chuyển tiếp. Trước đây, tôi đã viết phân tích cú pháp XML của riêng mình trong khi cẩn thận không đưa ra bất kỳ giả định nào về việc đặt hàng hoặc không có các thẻ mà tôi không biết trong tương lai. Nếu bạn có thể tải toàn bộ tệp XML, XPATH có thể sẽ hoạt động khá tốt. Mặt khác, bên trái của bạn với một số phân tích luồng phức tạp hơn
Alan

Tôi sẽ đề nghị xem xét JSON
Basile Starynkevitch

7

Từ một người đã phải phân tích nhiều định dạng tệp, tôi có ý kiến ​​về điều này từ một quan điểm khác với hầu hết.

  • Làm cho số ma thuật trở nên rất độc đáo để các trình phát hiện định dạng tệp của mọi người cho các định dạng khác không xác định nhầm nó là của bạn. Nếu bạn sử dụng nhị phân, hãy phân bổ 8 hoặc 16 byte được tạo ngẫu nhiên khi bắt đầu định dạng nhị phân cho số ma thuật. Nếu bạn sử dụng XML, hãy phân bổ một không gian tên thích hợp trong miền của bạn để nó không thể xung đột với người khác. Nếu bạn sử dụng JSON, chúa sẽ giúp bạn. Có lẽ bây giờ ai đó đã sắp xếp một giải pháp cho sự ghê tởm của một định dạng.

  • Lập kế hoạch cho khả năng tương thích ngược. Lưu trữ số phiên bản của định dạng bằng cách nào đó để các phiên bản phần mềm sau này của bạn có thể xử lý các khác biệt.

  • Nếu tệp có thể lớn hoặc có những phần mà mọi người có thể muốn bỏ qua vì một số lý do, hãy đảm bảo có một cách hay để làm điều này. XML, JSON và hầu hết các định dạng văn bản khác đặc biệt khủng khiếp vì điều này, vì chúng buộc người đọc phải phân tích tất cả dữ liệu giữa phần tử bắt đầu và kết thúc ngay cả khi họ không quan tâm đến nó. EBML có phần tốt hơn vì nó lưu trữ độ dài của các phần tử, cho phép bạn bỏ qua tất cả từ đầu đến cuối. Nếu bạn tạo một định dạng nhị phân tùy chỉnh, có một thiết kế khá phổ biến nơi bạn lưu trữ một định danh chunk và độ dài là điều đầu tiên trong tiêu đề, và sau đó người đọc có thể bỏ qua toàn bộ khối.

  • Lưu trữ tất cả các chuỗi trong UTF-8.

  • Nếu bạn quan tâm đến khả năng mở rộng dài hạn, hãy lưu trữ tất cả các số nguyên ở dạng có độ dài thay đổi.

  • Tổng kiểm tra là tốt vì nó cho phép người đọc hủy bỏ ngay lập tức dữ liệu không hợp lệ, thay vì có khả năng bước vào các phần của tệp có thể tạo ra kết quả khó hiểu.


+1 vì đã khiến tôi nhận ra rằng tôi không phải là người duy nhất nghĩ rằng json là một sự ghê tởm của một định dạng.
RubberDuck

Tại sao ghét cho json? Chỉ cần đặt một chuỗi đã biết vào một vị trí đã biết để xác định định dạng. Vấn đề được giải quyết.
Esben Skov Pedersen

Nó không hoàn hảo, nhưng nó hoạt động trơn tru với javascript, phân tích cú pháp nhanh hơn XML và kích thước nhỏ hơn và vẫn có thể đọc được.
corylulu

1
"Tại sao ghét JSON?" Không hỗ trợ cho các nhận xét có thể đọc được của con người, thoát khỏi Unicode và một cú pháp kỳ lạ đòi hỏi tôi phải trích dẫn các khóa mặc dù chúng không bao giờ chứa khoảng trắng. Cộng với việc không thể mở rộng mọi thứ thông thường vì không ai nghĩ về việc đặt tên ... vào thời điểm bạn giải quyết vấn đề đó, bạn kết thúc với một thứ thậm chí còn tồi tệ hơn XML ở nơi đầu tiên, tất cả là vì lợi ích của việc tránh một số góc ngoặc?
Trejkaz

Vâng, nhưng như với tất cả mọi thứ với lập trình, sử dụng công cụ phù hợp cho công việc. Có những ứng dụng mà XML tốt hơn JSON và ngược lại.
corylulu

4

Vâng, có những lúc những gì bạn mô tả có thể là một cách tiếp cận rất xấu. Điều này là giả sử khi bạn nói 'tuần tự hóa' bạn đang nói về việc sử dụng khả năng của ngôn ngữ / khung để chỉ cần lấy một đối tượng và xuất trực tiếp đến một loại luồng nhị phân nào đó. Vấn đề là cấu trúc lớp thay đổi qua nhiều năm. Bạn có thể tải lại một tệp được tạo trong phiên bản trước của ứng dụng nếu tất cả các lớp của bạn thay đổi trong một phiên bản mới hơn không?

Để ổn định lâu dài định dạng tệp, tôi đã thấy tốt hơn nên xắn tay áo lên một chút bây giờ và đặc biệt viết các phương thức 'tuần tự hóa' / 'truyền phát' của riêng bạn trong các lớp học. tức là, tự xử lý việc ghi các giá trị vào luồng. Viết tiêu đề khi bạn nêu mô tả phiên bản định dạng và sau đó dữ liệu bạn muốn lưu theo thứ tự bạn muốn. Về mặt đọc, việc xử lý các phiên bản khác nhau của định dạng tệp trở nên dễ dàng hơn rất nhiều.

Tất nhiên, tùy chọn khác là XML hoặc JSON. Không nhất thiết là lớn nhất cho nội dung nặng nhị phân, nhưng đơn giản và dễ đọc của con người ... một điểm cộng lớn cho khả năng tồn tại lâu dài.


Tôi đang tuần tự hóa bằng cách sử dụng protobuf-net ( code.google.com/p/protobuf-net ) có thể mở rộng. Nhưng điểm của bạn là hợp lệ, tuy nhiên, tôi không nghĩ rằng đó là bất kỳ phương pháp định dạng tệp nào miễn nhiễm với điều này.
corylulu

Đúng ... đó là lý do tại sao tôi nói đôi khi bạn chỉ cần làm bẩn tay và xử lý thứ tự dữ liệu được ghi và tải thủ công.
GrandmasterB

Ứng dụng tôi đang xây dựng rất năng động và có quá nhiều giá trị cho những thứ tương tự.
corylulu

1
Ứng dụng càng phức tạp, điều quan trọng hơn là phải kiểm soát rất tốt định dạng tệp. Hãy nhớ rằng tôi không nói mỗi lớp không nên có đầu ra có thể truyền phát riêng ... chỉ là bạn nên kiểm soát điều đó cho mỗi lớp. Sau đó, chỉ cần gọi những thói quen.
GrandmasterB

Vâng, tôi có các phương pháp nâng cấp các phiên bản kế thừa lên các phiên bản hiện đại và tôi có một bố cục rất rõ ràng về cách các lớp học của tôi được trình bày. Tôi không quá lo lắng về điều đó, nhưng tôi đồng ý rằng nó quan trọng. Tôi đã làm việc này gần một năm, vì vậy tôi có một cái nhìn khá rõ ràng về cách cấu trúc của nó hoạt động.
corylulu

1

Tôi cũng rất thích nghe câu trả lời cho câu hỏi này từ những người có nhiều năm kinh nghiệm hơn bản thân tôi.

Cá nhân tôi đã triển khai một số định dạng tệp cho công việc của mình và tôi đã chuyển sang sử dụng định dạng tệp XML. Yêu cầu và phần cứng của tôi mà tôi tương tác luôn thay đổi và không có gì để nói tôi sẽ cần thêm gì vào định dạng trong tương lai. Một trong những ưu điểm chính của XML là nó có cấu trúc bán cấu trúc . Vì lý do này, tôi thường tránh Tuần tự hóa XML tự động mà .NET cung cấp vì tôi tin rằng nó buộc nó phải mong đợi một định dạng chính xác.

Mục tiêu của tôi là tạo ra một định dạng XML cho phép các yếu tố và thuộc tính mới được thêm vào trong tương lai và để thứ tự các thẻ không quan trọng bất cứ khi nào có thể. Nếu bạn chắc chắn rằng bạn có thể tải toàn bộ tệp của mình vào bộ nhớ thì XPATH có lẽ là một lựa chọn tốt.

Nếu bạn đang xử lý các tệp đặc biệt lớn hoặc vì các lý do khác không thể tải toàn bộ tệp cùng một lúc, thì có lẽ bạn còn sử dụng XmlStreamReader và quét các phần tử đã biết và đệ quy vào các phần tử đó bằng ReadSubtree và quét lại ...


Câu trả lời này không hướng nhiều đến Q, trang web này không có nghĩa là một bảng thảo luận mà là dành cho Q & A không đầu cơ. Bạn có một số điểm hợp lệ được đưa ra trong câu trả lời của mình có thể được sử dụng để tranh luận về lý do tại sao cách tiếp cận của người hỏi là tốt hoặc không tốt, nhưng nó không tập trung lắm. Hãy tập trung trả lời của bạn vào câu hỏi nhiều hơn một chút, cảm ơn!
Jimmy Hoffa

@JimmyHoffa Mặc dù câu trả lời của tôi cũng hỗ trợ câu hỏi của OP, tôi đã nói rõ rằng tôi đang đề xuất một cách tiếp cận bán cấu trúc XML .. nhưng tôi hiểu ý của bạn, tôi có thể chỉnh sửa
Alan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.