Apakah ada cara yang tepat untuk membuat format file?

12

Saya sedang membangun format file berpemilik untuk aplikasi yang saya tulis di C # .NET untuk menyimpan informasi simpanan dan mungkin di masa mendatang aset proyek. Apakah ada standar tentang cara melakukan ini dengan cara apa pun? Saya hanya pergi ke Serializeobjek saya menjadi biner dan membuat header yang akan memberi tahu saya bagaimana mengurai file. Apakah ini pendekatan yang buruk?

corylulu
sumber
2
Saya akan menghindari BinaryFormatter.
CodesInChaos
3
Pendekatan apa pun (dari jawaban) yang Anda pilih, selalu sertakan nomor versi dalam format! Pertanyaan Anda sudah menunjukkan bahwa itu mungkin berubah, dan nomor versi akan menghemat banyak usaha jika Anda harus backwarsd ​​kompatibel.
Jan Doggen
Jangan lupa untuk mendokumentasikan formatnya dengan benar
Basile Starynkevitch

Jawaban:

11

Metode paling mudah mungkin adalah membuat cerita bersambung struktur Anda ke XML menggunakan XMLSerializerkelas. Anda mungkin tidak perlu membuat tajuk dan struktur tubuh yang terpisah - tetapi serialkan semua aset ke dalam XML. Ini memungkinkan Anda untuk dengan mudah memeriksa / mengedit struktur file Anda di luar program Anda sendiri, dan mudah dikelola.

Namun, jika struktur file Anda benar-benar kompleks, mengandung banyak aset yang berbeda dari jenis yang berbeda, sehingga membuat serialisasi seluruh struktur menjadi XML terlalu berat, Anda mungkin melihat membuat serial setiap aset secara terpisah dan menyusunnya menjadi satu paket menggunakan Packagingperpustakaan di C # . Ini pada dasarnya bagaimana .docx, .xslx, .pptx, dan format file office lainnya dibuat.

pswg
sumber
Ya, proyek saya jauh lebih kompleks dari itu, tetapi saya juga berusaha membuatnya lebih mudah dibaca pengguna karena kami mungkin menggunakan ini dalam bidang dalam konteks berlisensi. Saat ini saya menggunakan protobuf-netuntuk mengelompokkan data saya dan banyak yang berfungsi dengan baik. Tapi saya harus membuat serial potongan-potongan secara terpisah, jadi apa yang Anda bicarakan dengan perpustakaan Pengemasan terdengar seperti yang saya butuhkan.
corylulu
7
Ya tuhan bukan XML
James
2
@ James yeah XML memiliki kelemahannya, tentu saja. Saya mendukung pengemasan dan XML dalam banyak kasus dengan alasan yang sama: 1. ini adalah kerangka kerja yang sudah ada, sehingga membutuhkan usaha yang rendah. 2. Mudah bagi sistem lain untuk mendukung, karena standar yang diterima secara luas. 3. Sangat mudah bagi manusia untuk memeriksa file yang dihasilkan untuk memverifikasi proses serialisasi.
pswg
XML memiliki kelebihan, tetapi karena kelebihan itulah saya tidak suka menggunakan serializer XML. Saya percaya ini membutuhkan XML dalam format tertentu. XML adalah format semi-terstruktur, yang memungkinkan format file saya berubah seiring waktu dan masih kompatibel dan maju. Di masa lalu, saya telah menulis parsing XML saya sendiri sambil berhati-hati untuk tidak membuat asumsi tentang pemesanan atau tidak ada tag yang tidak saya sadari di masa depan. Jika Anda dapat memuat seluruh file XML, XPATH mungkin akan bekerja dengan cukup baik. Jika tidak, sebelah kiri Anda dengan aliran parsing yang lebih rumit
Alan
Saya sarankan melihat ke JSON
Basile Starynkevitch
7

Dari seseorang yang harus mem-parsing banyak format file, saya punya pendapat tentang ini dari sudut pandang yang berbeda untuk sebagian besar.

  • Buat angka ajaib sangat unik sehingga detektor format file orang untuk format lain tidak salah mengidentifikasi sebagai milik Anda. Jika Anda menggunakan biner, alokasikan 8 atau 16 byte yang dihasilkan secara acak di awal format biner untuk angka ajaib. Jika Anda menggunakan XML, alokasikan namespace yang tepat di domain Anda sehingga tidak dapat berbenturan dengan orang lain. Jika Anda menggunakan JSON, tuhan bantu Anda. Mungkin seseorang telah memilah solusi untuk kekejaman format sekarang.

  • Rencanakan kompatibilitas mundur. Simpan nomor versi format dengan cara apa pun sehingga versi perangkat lunak Anda nanti dapat mengatasi perbedaan.

  • Jika file bisa besar, atau ada bagian yang orang mungkin ingin lewati karena alasan tertentu, pastikan ada cara yang bagus untuk melakukan ini. XML, JSON dan sebagian besar format teks lainnya sangat buruk untuk ini, karena mereka memaksa pembaca untuk mem-parsing semua data antara elemen awal dan akhir bahkan jika mereka tidak peduli. EBML agak lebih baik karena menyimpan panjang elemen, memungkinkan Anda untuk melewati semua jalan sampai akhir. Jika Anda membuat format biner kustom, ada desain yang cukup umum di mana Anda menyimpan pengidentifikasi potongan dan panjang sebagai hal pertama di header, dan kemudian pembaca dapat melewati seluruh potongan.

  • Simpan semua string di UTF-8.

  • Jika Anda peduli tentang ekstensibilitas jangka panjang, simpan semua bilangan bulat dalam bentuk variabel panjang.

  • Checksum sangat bagus karena memungkinkan pembaca untuk segera membatalkan data yang tidak valid, daripada berpotensi melangkah ke bagian file yang dapat menghasilkan hasil yang membingungkan.

Trejkaz
sumber
+1 untuk membuat saya menyadari bahwa saya bukan satu-satunya orang yang berpikir json adalah kekejaman dari suatu format.
RubberDuck
Kenapa benci untuk json? Cukup masukkan string yang dikenal di lokasi yang dikenal untuk mengidentifikasi format. Masalah terpecahkan.
Esben Skov Pedersen
Ini tidak sempurna, tetapi berfungsi mulus dengan javascript, lebih cepat diurai daripada XML dan ukuran lebih kecil, dan masih dapat dibaca manusia.
corylulu
1
"Kenapa benci untuk JSON?" Tidak ada dukungan untuk komentar yang bisa dibaca orang, omong kosong lolos dari Unicode, dan sintaks aneh yang mengharuskan saya untuk mengutip kunci meskipun mereka tidak pernah mengandung spasi. Ditambah ketidakmampuan biasa untuk memperpanjang hal-hal karena tidak ada yang memikirkan penempatan nama ... pada saat Anda menyelesaikannya, Anda berakhir dengan sesuatu yang terlihat lebih buruk daripada XML di tempat pertama, semua untuk apa, manfaat menghindari sudut pandang tertentu kurung?
Trejkaz
Ya, tetapi seperti semua hal dengan pemrograman, gunakan alat yang tepat untuk pekerjaan itu. Ada aplikasi di mana XML lebih baik dari JSON dan sebaliknya.
corylulu
4

Nah, ada kalanya yang Anda gambarkan bisa menjadi pendekatan yang sangat buruk. Ini mengasumsikan ketika Anda mengatakan 'cerita bersambung' Anda sedang berbicara tentang menggunakan kemampuan bahasa / kerangka kerja untuk hanya mengambil objek dan output langsung ke semacam aliran biner. Masalahnya adalah struktur kelas berubah selama bertahun-tahun. Apakah Anda dapat memuat ulang file yang dibuat dalam versi aplikasi Anda sebelumnya jika semua kelas Anda berubah menjadi yang lebih baru?

Untuk stabilitas jangka panjang dari format file, saya merasa lebih baik menyingsingkan lengan baju Anda sekarang dan secara khusus menulis metode 'serialisasi' / 'streaming' Anda sendiri di dalam kelas Anda. yaitu, secara manual menangani penulisan nilai ke aliran. Tulis header saat Anda menyatakan yang menggambarkan versi format, dan kemudian data yang Anda inginkan disimpan dalam urutan yang Anda inginkan. Di sisi membaca, menangani berbagai versi format file menjadi jauh lebih mudah.

Pilihan lain tentu saja adalah XML atau JSON. Belum tentu yang terbaik untuk konten biner berat, tetapi sederhana dan dapat dibaca manusia ... plus besar untuk kelangsungan jangka panjang.

GrandmasterB
sumber
Saya membuat serial menggunakan protobuf-net ( code.google.com/p/protobuf-net ) yang dapat diperpanjang. Tetapi poin Anda valid, namun, saya tidak berpikir bahwa mereka adalah metode format file apa pun yang kebal terhadap ini.
corylulu
Yap ... itu sebabnya saya mengatakan kadang-kadang Anda hanya perlu membuat tangan Anda kotor dan menangani urutan data ditulis & dimuat secara manual.
GrandmasterB
Aplikasi yang saya bangun jauh dari dinamis dan memiliki terlalu banyak nilai untuk hal seperti itu.
corylulu
1
Semakin rumit aplikasi, semakin penting untuk memiliki kontrol yang sangat baik atas format file. Ingatlah bahwa saya tidak mengatakan bahwa setiap kelas tidak boleh memiliki keluaran yang dapat di-stream-kan sendiri ... hanya saja Anda harus mengontrolnya untuk setiap kelas. Kemudian panggil saja rutinitas itu.
GrandmasterB
Ya, saya memiliki metode yang meningkatkan versi legacy ke versi modern dan saya memiliki tata letak yang sangat jelas tentang bagaimana kelas saya ditata. Saya tidak terlalu khawatir tentang itu, tetapi saya setuju itu penting. Saya telah mengerjakan ini selama hampir setahun, jadi saya memiliki pandangan yang cukup jelas tentang bagaimana struktur itu bekerja.
corylulu
1

Saya juga akan senang mendengar jawaban pertanyaan ini dari orang-orang dengan tahun pengalaman lebih dari diriku sendiri.

Saya secara pribadi telah mengimplementasikan beberapa format file untuk pekerjaan saya, dan saya telah pindah ke menggunakan format file XML. Persyaratan dan perangkat keras saya yang berinteraksi dengan saya berubah setiap saat, dan tidak ada yang tahu apa yang perlu saya tambahkan ke format di masa mendatang. Salah satu keunggulan utama XML adalah semi-terstruktur . Untuk alasan ini, saya biasanya menghindari Serialisasi XML otomatis yang disediakan oleh .NET karena saya percaya itu memaksa untuk mengharapkan format yang tepat.

Tujuan saya adalah membuat format XML yang memungkinkan elemen dan atribut baru ditambahkan di masa depan dan agar urutan tag tidak menjadi masalah bila memungkinkan. Jika Anda yakin bahwa Anda dapat memuat seluruh file Anda ke dalam memori maka XPATH mungkin merupakan pilihan yang baik.

Jika Anda berurusan dengan file yang sangat besar, atau karena alasan lain tidak dapat memuat file sekaligus, maka Anda mungkin dibiarkan menggunakan XmlStreamReader dan memindai elemen yang diketahui dan berulang ke elemen-elemen tersebut dengan ReadSubtree dan memindai lagi ...

Alan
sumber
Jawaban ini tidak terlalu ditujukan kepada Q, situs ini tidak dimaksudkan untuk menjadi papan diskusi tetapi lebih ditujukan untuk tanya jawab non-spekulatif. Anda memiliki beberapa poin valid yang dibuat dalam jawaban Anda yang dapat digunakan untuk mendebat saran mengapa pendekatan si penanya itu baik atau tidak, tetapi itu tidak terlalu terfokus. Harap fokuskan jawaban Anda pada pertanyaan lebih sedikit, terima kasih!
Jimmy Hoffa
@JimmyHoffa Sementara jawaban saya juga mendukung pertanyaan OP, saya menjelaskan bahwa saya menyarankan pendekatan semi-terstruktur XML .. tapi saya mengerti maksud Anda, saya dapat mengedit
Alan