Bir dosyanın başlangıcında yalnızca sonunda bildiğiniz bir şeyi yazma


9

Arka plan: EBML dosyası yazmak için mikro kontrolör C kodu yazıyorum. EBML, iç içe öğelere sahip bir ikili XML gibidir, ancak başlangıç ​​ve bitiş etiketleri yerine bir başlangıç ​​kimliği, uzunluğu ve ardından veriler vardır. Bunu düşük güçlü bir uygulamada harici Flash'a yazıyorum, bu yüzden flaş erişimini minimumda tutmak istiyorum. Bellek de sınırlıdır, çünkü hiçbir şey kolay değildir.

EBML öğesinin tamamını bellekte tutabildiğimde, bunu oluşturmak kolaydır, çünkü bu uzunluğun ne olduğunu öğrendikten sonra geri dönüp her bir öğenin uzunluğunu doldurabilirim. Sorun, tüm elemanı hafızada tutamadığım zaman ne yapacağım. Gördüğüm seçenekler:

  • Bildiklerimi yaz, sonra geri dön ve uzunlukları ekle (en kolay, ancak istediğimden daha fazla flaş erişimi ekliyor)
  • Yazmaya başlamadan önce her bir öğenin uzunluğunu hesaplayın (nispeten kolay, ancak çok fazla işlemci süresi)
  • Modları belleğimi doldurduktan sonra değiştiriyorum, böylece verilerde devam edeceğim, ancak sadece bellekte zaten ayrılmış olan elemanların uzunluklarını hesaplamak için. Sonra bellekte ne yazıyorum ve geri dönüp kaldığım yerden verileri işlemeye devam et. (Şimdiye kadarki favori seçeneğim)
  • Yazılmaları gerektiğinde ve son uzunlukları henüz bilinmiyorsa öğelere maksimum veya en kötü durum uzunluğu verin. (Yukarıdakilerden daha kolay, ancak geri tepebilir ve alan israf edebilir)

Soru: Bu, insanların düşündüğü nispeten yaygın bir sorun gibi görünüyor. Bazı veri paketleri oluştururken de olabileceğini biliyorum. Burada özlediğim daha iyi / daha yaygın / daha kabul görmüş bir teknik var mı? Ya da sadece arayabileceğim sorun için bazı terimler?


1
/ sccs şu şekilde çalışır: yazma bittikten sonra dosyanın başlangıcında tüm baytların sağlama toplamını yazar. Atomik olarak gerekli dosya işlemlerini gerçekleştirebilen (örneğin Solaris) Unix'lerde harika çalışır ve Unix'lerde bunu yapamayan garip dağınık sorunlara neden olur, örneğin Linux
gnat

Yanıtlar:


2

Yükünüzün ne kadar süreceğini bilmiyorsanız, pozisyonu hatırlayamasanız ve daha sonra uzunluğu dolduramasanız bile bu nadiren endişe sebebidir:

Sadece "bilinmeyen boyut" u not edin.

Bu özellik EBML elemanlarından oluşan yüke bağlıdır ve aşağıdaki eleman geçerli bir alt eleman olmamalıdır.

İsterseniz, daha sonra elde edilen EBML'yi çevrimdışı olarak istediğiniz şekilde, örneğin "bilinmeyen boyut yok, minimum boyut" veya "minimum boyut, bilinmeyen boyutlardan kaçın" şeklinde kurallı hale getirebilirsiniz.


Ayrıntılar için matroska.org'daki EBML RFC Taslağına bakın.


Bu harika! Bu farkında olmadığım bir şeydi ve temel problemden kaçınıyor, ama yine de temel problemi çözmek için iyi bir yol konusunda rehberlik etmek istiyorum. Bilinmeyen boyutta bir eleman kullanmak, gelecekteki uyumluluğu sınırlayabiliyor gibi görünüyor, çünkü eski yazılımlar yeni elemanlardan erken çıkacaktır.
pscheidler

Doğru DTD'ye ihtiyacınız var veya EBML'yi gerçekten çözemezsiniz. Bilinmeyen tüm öğeler boyutlandırılmışsa bunları atlayabilirsiniz, ancak bu yeterli mi? Çevrimdışı olarak depolamak istediğiniz EBML'yi varsa, son işlemden geçirmeniz yeterlidir.
Tekilleştirici

Genişleyecek olan kendi şemamızı kullanıyoruz. Eski yazılımların nihayetinde bazı verileri atlamak zorunda kalacağı bilgisi ile tasarlanmıştır. Ama bu EBML'nin farkında olmadığım harika bir özelliği, bu yüzden cevabı kabul ediyorum.
pscheidler

0

Sabit sayıda alt öğeye sahip tek bir öğe çok büyükse, belki de onu şemaya bölmeye çalışmalısınız. Bu formatı bilmiyorum, ama büyük olasılıkla bu formatta maksimum bir uzunluk tanımlayabilirsiniz.

Diziler için maksimum alt öğe sayısını ve sonraki dosyada kalan "akış" tanımlamayı deneyebilirsiniz

Maksimum bellek boyutunu aşan öğeler için çift içeren bir yığın hazırlayın: ayrılmış eleman uzunluğu konumu ve uzunluk sayacı. Pop'ta geçerli sayacı geçerli işaretçiye kaydedin ve değerini sonraki sayaca ekleyin.

Genel olarak çok büyük elemanların sayısını en aza indirmeye çalışın


Muhtemelen kendi EBML unsurları için yapabilirdi, ancak bu yine de ana unsurda ona yardım etmiyor.
Tekilleştirici

Fikriniz işe yarayacaktır, ancak şemayı büyük öğelerden kaçınmak için kısıtlamak yerine, büyük öğeleri işleyebilecek bir sistem oluşturmayı tercih ederim.
pscheidler

Bu çözüm büyük elemanlar için de işe yarayacaktır, sadece yığın boyutuna dikkat edin. Şema söz konusuysa ... bunu uygulamalarınızın kullandığı bir dil olarak düşünün, biri karmaşık bir dili işleyemezse, diğeri ayarlamalı veya bir çevirmen gerekir. Birçok geliştirici (en azından bildiğim C / C ++ olanlar) bir yangın gibi şema / tasarım değişikliklerinden kaçınma eğilimindedir ve bu daha sonra zayıf bir sistemle sonuçlanır. Başka bir bileşen ayarlayamazsa, belki de zayıf bir şekilde ayrışır / tasarlanır. Değiştirmemek için başka nedenler varsa, muhtemelen farklı bir donanım kullanmayı düşünmelisiniz
Whoot

0

ÖPÜCÜK ve YAGNI.
Seçenek # 1'i seçin ve gerçek bir sorun haline gelirse - ancak o zaman tekrarlayın.

En azından benzer ikili formatlara sahip benzer kullanım durumları için, sadece bir çift değerin bu şekilde doldurulması gerektiğinde, bu en basit / en kolay / en iyi çözümdür. Bunu her veri parçasında yapmak zorundaysanız - o zaman mimaride bir kusur olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.