2011-03-18 17 views
5

में रिकॉर्ड के 1000s के साथ बाइनरी फ़ाइल प्रारूप मैं एक बाइनरी स्ट्रीम में क्रमबद्ध करने के लिए एक सरणी मॉडल ऑब्जेक्ट्स रखना चाहता हूं। मॉडल क्लास में मुख्य रूप से स्ट्रिंग और पूर्णांक गुण होंगे।सी #

मेरा मानना ​​है कि मैं कक्षा को [सीरियलज़ेबल] के रूप में चिह्नित कर सकता हूं और बाइनरी फॉर्मैटर का उपयोग कर सकता हूं, हालांकि मुझे यह जानने में दिलचस्पी होगी कि आपको लगता है कि यह सबसे अच्छा तरीका है कि मेरी प्राथमिकता छोटी फ़ाइल के रूप में है कम बैंडविड्थ कनेक्शन पर स्थानांतरण के लिए जितना संभव हो (मैं फ़ाइल को ज़िप/अनजिप भी कर सकता हूं)।

फ़ाइल में रिकॉर्ड्स के 1000s हो सकते हैं, इसलिए आदर्श रूप से मैं रिकॉर्ड में डिस्क रिकॉर्ड से पढ़ने और रिकॉर्ड में डिस्क रिकॉर्ड से पढ़ने में सक्षम होना चाहता हूं, बिना किसी फ़ाइल में पूरी फाइल को कभी भी।

तो मेरी प्राथमिकताएं हैं: छोटी फ़ाइल आकार और कुशल स्मृति उपयोग।

शायद इसके लिए एक पूर्व-लिखित ढांचा है? एक्सएमएल और सीएसवी फाइलों के साथ ऐसा करना आसान लगता है! उम्मीद है कि यह एक कस्टम बाइनरी प्रारूप के साथ भी है।

धन्यवाद

उत्तर

6

मुझे सुझाव है कि protobuf.net जो बहुत ही कुशल है।

ऐसा कहकर, यह आपके संग्रह में व्यक्तिगत वस्तुओं को क्रमबद्ध करने/deserialsing को संभालने में सक्षम नहीं होगा। वह हिस्सा आपको स्वयं को लागू करने की आवश्यकता है।

  • एक समाधान यह है कि: किसी फ़ोल्डर में ऑब्जेक्ट्स को व्यक्तिगत फ़ाइलों के रूप में स्टोर करें। फ़ाइल नाम में एक संदर्भ होगा जिसमें नाम के आधार पर, आपको वह ऑब्जेक्ट मिल सकता है जिसकी आपको आवश्यकता है।

  • दूसरा एक फ़ाइल है लेकिन एक इंडेक्स फ़ाइल रखना है जो फ़ाइल में सभी ऑब्जेक्ट्स और उनकी स्थिति की एक सूची रखती है। यह बहुत जटिल है क्योंकि जब आप किसी ऑब्जेक्ट को फ़ाइल के बीच में सहेज रहे हैं, तो आपको अन्य सभी पते ले जाना होगा, और शायद बी-पेड़ अधिक प्रभावी है।

+2

दूसरे विकल्प के लिए: [FileDB] (http://nuget.org/List/Packages/FileDB)। –

+0

धन्यवाद मार्टिन्हो। मुझे फाइलडीबी पसंद आया! – Aliostad

1

आप BinaryFormatter उपयोग कर सकते हैं। यह एक छोटी फ़ाइल चाहते हैं, लेकिन केवल आप जानते हैं कि यह आपके डोमेन के लिए सबसे अच्छा समाधान है या नहीं। मुझे नहीं लगता कि आप एक समय में एक रिकॉर्ड पढ़ सकते हैं।

इस समय मेरे पास एकमात्र उदाहरण कोड DataSet है। ये एक्सटेंशन विधियां (डी) एक कस्टम डेटासेट को क्रमबद्ध करेंगी, जो, यदि मैं सही ढंग से याद करता हूं, तो बाइनरीफॉर्मेटर का उपयोग करने वाले प्रकार का सबसे आसान तरीका था।

public static TDataSet LoadBinary<TDataSet>(Stream stream) where TDataSet : DataSet 
{ 
    var formatter = new BinaryFormatter(); 
    return (TDataSet)formatter.Deserialize(stream); 
} 

public static void WriteBinary<TDataSet>(this TDataSet dataSet, Stream stream) where TDataSet : DataSet 
{ 
    dataSet.RemotingFormat = SerializationFormat.Binary; 
    var formatter = new BinaryFormatter(); 
    formatter.Serialize(stream, dataSet); 
} 

तुम भी (सी # 4.0 संक्षेप में, Albahari & Albahari के अनुसार) DataContractSerializer पर एक नज़र है, जो नेट के नए 'मानक' क्रमबद्धता से निपटने का तरीका है लग सकता है। उस स्थिति में, आप Best Practices: Data Contract Versioning पढ़ना भी चाहेंगे। नीचे उदाहरण हैं कि कैसे (डी) एक्सएमएल और जेएसओएन में क्रमबद्ध करें, भले ही वे आपकी स्थिति पर सीधे लागू न हों (क्योंकि आप छोटी फाइलें चाहते थे)। लेकिन आप फ़ाइलों को संपीड़ित कर सकते हैं।

/// <summary> 
/// Converts this instance to XML using the <see cref="DataContractSerializer"/>. 
/// </summary> 
/// <typeparam name="TSerializable"> 
/// A type that is serializable using the <see cref="DataContractSerializer"/>. 
/// </typeparam> 
/// <param name="value"> 
/// The object to be serialized to XML. 
/// </param> 
/// <returns> 
/// Formatted XML representing this instance. Does not include the XML declaration. 
/// </returns> 
public static string ToXml<TSerializable>(this TSerializable value) 
{ 
    var serializer = new DataContractSerializer(typeof(TSerializable)); 
    var output = new StringWriter(); 
    using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented }) 
    { 
     serializer.WriteObject(writer, value); 
    } 
    return output.GetStringBuilder().ToString(); 
} 

/// <summary> 
/// Converts this instance to XML using the <see cref="DataContractSerializer"/> and writes it to the specified file. 
/// </summary> 
/// <typeparam name="TSerializable"> 
/// A type that is serializable using the <see cref="DataContractSerializer"/>. 
/// </typeparam> 
/// <param name="value"> 
/// The object to be serialized to XML. 
/// </param> 
/// <param name="filePath">Path of the file to write to.</param> 
public static void WriteXml<TSerializable>(this TSerializable value, string filePath) 
{ 
    var serializer = new DataContractSerializer(typeof(TSerializable)); 
    using (var writer = XmlWriter.Create(filePath, new XmlWriterSettings { Indent = true })) 
    { 
     serializer.WriteObject(writer, value); 
    } 
} 

/// <summary> 
/// Creates from an instance of the specified class from XML. 
/// </summary> 
/// <typeparam name="TSerializable">The type of the serializable object.</typeparam> 
/// <param name="xml">The XML representation of the instance.</param> 
/// <returns>An instance created from the XML input.</returns> 
public static TSerializable CreateFromXml<TSerializable>(string xml) 
{ 
    var serializer = new DataContractSerializer(typeof(TSerializable)); 

    using (var stringReader = new StringReader(xml)) 
    using (var reader = XmlReader.Create(stringReader)) 
    { 
     return (TSerializable)serializer.ReadObject(reader); 
    } 
} 

/// <summary> 
/// Creates from an instance of the specified class from the specified XML file. 
/// </summary> 
/// <param name="filePath"> 
/// Path to the XML file. 
/// </param> 
/// <typeparam name="TSerializable"> 
/// The type of the serializable object. 
/// </typeparam> 
/// <returns> 
/// An instance created from the XML input. 
/// </returns> 
public static TSerializable CreateFromXmlFile<TSerializable>(string filePath) 
{ 
    var serializer = new DataContractSerializer(typeof(TSerializable)); 

    using (var reader = XmlReader.Create(filePath)) 
    { 
     return (TSerializable)serializer.ReadObject(reader); 
    } 
} 

public static T LoadJson<T>(Stream stream) where T : class 
{ 
    var serializer = new DataContractJsonSerializer(typeof(T)); 
    object readObject = serializer.ReadObject(stream); 
    return (T)readObject; 
} 

public static void WriteJson<T>(this T value, Stream stream) where T : class 
{ 
    var serializer = new DataContractJsonSerializer(typeof(T)); 
    serializer.WriteObject(stream, value); 
} 
1

मैं Sql सर्वर कॉम्पैक्ट का उपयोग कर serializing बिना वस्तुओं के रूप में अपनी वस्तुओं को स्टोर करने की सिफारिश करेंगे, यह काफी हल्के और बहुत तेज है, मैं सर्वर पर अनुरोध का एक बहुत की सेवा में उच्च पेलोड के तहत इस्तेमाल किया।

मैं आपके डेटा को द्विआधारी प्रारूप (क्रमबद्ध) में संग्रहीत करने की भी अनुशंसा नहीं करता क्योंकि यह उन वस्तुओं को बदलने के लिए एक शानदार दर्द होगा जब आप स्टोर करने जा रहे हैं। यह भी दर्दनाक है अगर आपको यह देखना है कि आप क्या स्टोर कर रहे हैं, क्योंकि आपको पूरे संग्रह को deserialize करना है।

भेजने के लिए मैं आवश्यक होने पर ज़िप-संपीड़न के साथ एक्सएमएल-क्रमबद्धरण का उपयोग करना पसंद करता हूं। एक्सएमएल प्रारूप डिबगिंग को अधिक आसान बनाता है अगर आपको यह देखने की ज़रूरत है कि आप क्या भेज रहे हैं या कुछ परीक्षण कर रहे हैं।

0

यदि आप इसे छोटा करना चाहते हैं तो इसे स्वयं करें। केवल आवश्यक डेटा को स्टोर करना सुनिश्चित करें। उदाहरण के लिए, यदि आपके पास केवल 255 अलग-अलग मान हैं तो बाइट का उपयोग करें।

http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx

मैं लगभग हमेशा एक सरल संरचना इस तरह डाटा स्टोर करने के लिए उपयोग

आईडी (ushort)

data_size (uint) आकार data_size की

डेटा

केवल उस जानकारी को स्टोर करें जो आपके पास है और इस बारे में नहीं सोचें कि इसका उपयोग कैसे किया जा रहा है। जब आप इसे लोड करते हैं तो आप विचार करते हैं कि आप डेटा का उपयोग कैसे करना चाहते हैं।

0

मैं ऑब्जेक्ट्स के लिए बाइनरीफॉर्मेटर के साथ चिपकने का प्रयास करता हूं, या शायद कहीं और protobuf.net जैसा सुझाव दिया गया है।

यदि इसका यादृच्छिक अभिगम पहलू बहुत महत्वपूर्ण है (रिकॉर्ड द्वारा रिकॉर्ड पढ़ना और जोड़ना) तो आप एक ज़िप फ़ाइल (या इसी तरह) को एक इंडेक्स फ़ाइल युक्त देखना चाहते हैं और प्रत्येक ऑब्जेक्ट को अपनी फ़ाइल में क्रमबद्ध किया गया है ज़िप (या शायद छोटे संग्रह में)।

इस तरह, आप प्रभावी ढंग से एक मिनी फाइल सिस्टम कर सकते हैं जो संपीड़ित है और आपको व्यक्तिगत रूप से अपने रिकॉर्ड तक पहुंच प्रदान करता है।

2

एक और विकल्प केवल एक निश्चित चौड़ाई वाले पाठ फ़ाइल स्वरूप को क्रमबद्ध करना है और ज़िप को संपीड़न को संभालने देना है। फिक्स्ड-चौड़ाई का मतलब है कि आप पूरी फ़ाइल को स्मृति में लोड करने की आवश्यकता के बिना प्रत्येक रिकॉर्ड के माध्यम से चलने के लिए आसानी से MemoryMappedFile का उपयोग कर सकते हैं।