एक संरचना में बाइनरी फ़ाइल पढ़ें

मैं सी # का उपयोग कर बाइनरी डेटा पढ़ने की कोशिश कर रहा हूं। मेरे पास उन फ़ाइलों में डेटा के लेआउट के बारे में सारी जानकारी है जिन्हें मैं पढ़ना चाहता हूं। मैं डेटा को "खंड द्वारा खंडित" पढ़ने में सक्षम हूं, यानी डेटा के पहले 40 बाइट्स को इसे स्ट्रिंग में परिवर्तित करने में सक्षम हूं, अगले 40 बाइट प्राप्त करें।

चूंकि डेटा के कम से कम तीन थोड़ा अलग संस्करण हैं, इसलिए मैं सीधे डेटा को डेटा में पढ़ना चाहता हूं। यह "रेखा से लाइन" पढ़ने से बस इतना अधिक सही लगता है।

मैंने निम्न दृष्टिकोण का प्रयास किया है लेकिन इसका कोई फायदा नहीं हुआ:

StructType aStruct;
int count = Marshal.SizeOf(typeof(StructType));
byte[] readBuffer = new byte[count];
BinaryReader reader = new BinaryReader(stream);
readBuffer = reader.ReadBytes(count);
GCHandle handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
aStruct = (StructType) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(StructType));
handle.Free();

स्ट्रीम एक खोला गया फ़ाइलस्ट्रीम है जिसमें से मैंने पढ़ना शुरू कर दिया है। Marshal.PtrToStructure का उपयोग करते समय मुझे AccessViolationExceptio n मिलता है।

स्ट्रीम में पढ़ने की कोशिश करने की तुलना में स्ट्रीम में अधिक जानकारी होती है क्योंकि मुझे फ़ाइल के अंत में डेटा में दिलचस्पी नहीं है।

संरचना को इस प्रकार परिभाषित किया गया है:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    public string FileDate;
    [FieldOffset(8)]
    public string FileTime;
    [FieldOffset(16)]
    public int Id1;
    [FieldOffset(20)]
    public string Id2;
}

इस सवाल को कम करने के लिए उदाहरण कोड मूल से बदल दिया गया है।

मैं फ़ाइल से एक संरचना में बाइनरी डेटा कैसे पढ़ूं?

0
जोड़ा संपादित
विचारों: 1

6 उत्तर

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

Encoding.ASCII.GetString()

तारों के लिए और

BitConverter.ToInt32()

पूर्णांक के लिए।

मुझे बाद में फ़ाइल के अधिक से अधिक विश्लेषण करने में सक्षम होना चाहिए, लेकिन इस संस्करण के लिए मैं कोड की कुछ पंक्तियों से दूर हो गया।

0
जोड़ा

सीधे structs में पढ़ना बुरा है - विभिन्न बाइट ऑर्डरिंग के कारण कई सी प्रोग्राम गिर गए हैं, फ़ील्ड के विभिन्न कंपाइलर कार्यान्वयन, पैकिंग, शब्द का आकार .......

आप बाइट द्वारा serialising और deserialising बाइट के सर्वश्रेष्ठ हैं। यदि आप चाहें तो सामान में निर्माण का उपयोग करें या बस बाइनरी रीडर में उपयोग करें।

0
जोड़ा
मैं भी असहमत हूं। जब प्रदर्शन महत्वपूर्ण होता है, या जब आपको बाइनरी सी ++ / सी # इंटरऑप की आवश्यकता होती है, तो सादे struct s लिखने का तरीका है।
जोड़ा लेखक Dmitri Nesteruk, स्रोत
मैं असहमत हूं, सीधे structs में पढ़ना कभी-कभी आपके डेटा को उपयोग करने योग्य वस्तु में लाने का सबसे तेज़ तरीका होता है। यदि आप प्रदर्शन उन्मुख कोड लिख रहे हैं तो यह बहुत उपयोगी हो सकता है। हां आपको संरेखण और पैकिंग के बारे में अवगत होना चाहिए और सुनिश्चित करें कि कोई एंडपॉइंट मशीन इसका उपयोग करेगी।
जोड़ा लेखक Joe, स्रोत

इसे इस्तेमाल करे:

using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
    BinaryFormatter formatter = new BinaryFormatter();
    StructType aStruct = (StructType)formatter.Deserialize(filestream);
}
0
जोड़ा
बाइनरीफॉर्मेटर के पास बाइनरी डेटा के लिए अपना प्रारूप है - यदि आप डेटा को पढ़ रहे / लिख रहे हैं तो यह ठीक है। उपयोगी नहीं है अगर आप किसी अन्य स्रोत से फ़ाइल प्राप्त कर रहे हैं।
जोड़ा लेखक russau, स्रोत

आपकी संरचना में समस्या स्ट्रिंग है। मैंने पाया कि बाइट / शॉर्ट / इंट जैसे मार्शलिंग प्रकार कोई समस्या नहीं है; लेकिन जब आपको स्ट्रिंग जैसे जटिल प्रकार में मार्शल करने की आवश्यकता होती है, तो आपको एक अप्रबंधित प्रकार की स्पष्ट रूप से नकल करने के लिए अपनी संरचना की आवश्यकता होती है। आप इसे मार्शल एट्रिब के साथ कर सकते हैं।

आपके उदाहरण के लिए, निम्नलिखित कार्य करना चाहिए:

[StructLayout(LayoutKind.Explicit)]
struct StructType
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileDate;

    [FieldOffset(8)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
    public string FileTime;

    [FieldOffset(16)]
    public int Id1;

    [FieldOffset(20)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 66)] //Or however long Id2 is.
    public string Id2;
}
0
जोड़ा

मुझे आपके कोड के साथ कोई समस्या नहीं दिख रही है।

बस मेरे सिर से बाहर, क्या होगा यदि आप इसे मैन्युअल रूप से करने का प्रयास करते हैं? क्या यह काम करता है?

BinaryReader reader = new BinaryReader(stream);
StructType o = new StructType();
o.FileDate = Encoding.ASCII.GetString(reader.ReadBytes(8));
o.FileTime = Encoding.ASCII.GetString(reader.ReadBytes(8));
...
...
...

भी आज़माएं

StructType o = new StructType();
byte[] buffer = new byte[Marshal.SizeOf(typeof(StructType))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();

फिर फ़ाइलस्ट्रीम से डेटा पढ़ने के बजाय अपने बाइनरी रीडर में बफर [] का उपयोग यह देखने के लिए करें कि क्या आपको अभी भी AccessViolation अपवाद मिलता है या नहीं।

मुझे इसका उपयोग करने में कोई भाग्य नहीं था   बाइनरीफॉर्मेटर, मुझे लगता है कि मुझे करना है   एक पूरी संरचना है जो मेल खाता है   फ़ाइल की सामग्री बिल्कुल।

यह समझ में आता है, बाइनरीफॉर्मेटर का अपना डेटा प्रारूप है, जो आपके साथ पूरी तरह से असंगत है।

0
जोड़ा

जैसा कि रोनी ने कहा, मैं बाइनरी रीडर का उपयोग करता हूं और प्रत्येक फ़ील्ड को व्यक्तिगत रूप से पढ़ता हूं। मुझे इस जानकारी के साथ आलेख का लिंक नहीं मिल रहा है, लेकिन यह देखा गया है कि प्रत्येक व्यक्तिगत क्षेत्र को पढ़ने के लिए बाइनरी रीडर का उपयोग मार्शल से तेज हो सकता है। PtrToStruct, यदि संरचना में 30-40 या उससे कम फ़ील्ड शामिल हैं। जब मैं इसे पाता हूं तो मैं लेख को लिंक पोस्ट करूंगा।

The article's link is at: http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C

जब structs की एक सरणी marshaling, PtrToStruct ऊपरी हाथ अधिक तेजी से लाभ, क्योंकि आप मैदान * सरणी लंबाई के रूप में क्षेत्र गिनती के बारे में सोच सकते हैं।

0
जोड़ा
वास्तव में यह है! अच्छा खोज :)
जोड़ा लेखक nevelis, स्रोत
मैं बस पढ़ रहा था: codeproject.com/KB/files/fastbinaryfileinput.aspx । क्या यह लेख आप सोच रहे हैं? लेखक नोट करते हैं: "मैंने पाया कि, लगभग 40 क्षेत्रों में, तीन दृष्टिकोणों के परिणाम लगभग बराबर थे, और उससे परे, ब्लॉक पढ़ने के दृष्टिकोण ऊपरी हाथ प्राप्त हुए।"
जोड़ा लेखक Neal Stublen, स्रोत