2010-08-21 10 views
5

मेरे पास एक सी प्रोग्राम द्वारा उत्पन्न एक फ्लैट फ़ाइल है। फ़ाइल में प्रत्येक रिकॉर्ड में डेटा के बाद एक निश्चित लंबाई शीर्षलेख होता है। शीर्षलेख में निम्न डेटा के आकार को इंगित करने वाला फ़ील्ड होता है। मेरा अंतिम लक्ष्य इस फ्लैट फ़ाइल को क्वेरी करने के लिए सी #/.NET प्रोग्राम लिखना है, इसलिए मैं सी # का उपयोग कर फ़ाइल को पढ़ने का सबसे प्रभावी तरीका ढूंढ रहा हूं।एक कस्टम बाइनरी फ्लैट फ़ाइल का विश्लेषण करने के लिए पसंदीदा तरीका?

मुझे निम्नलिखित कोड में लाइन 7 के .NET समकक्ष को खोजने में समस्या हो रही है। जहां तक ​​मैं कह सकता हूं, मुझे कई पढ़ना जारी रखना है (हेड के प्रत्येक फ़ील्ड के लिए बाइनरी रीडर का उपयोग करके) और उसके बाद हेडर के बाद डेटा प्राप्त करने के लिए एक को पढ़ना जारी रखें। मैं दो पढ़ने के संचालन में एक रिकॉर्ड को पार्स करने का एक तरीका सीखने की कोशिश कर रहा हूं (एक निश्चित लंबाई हेडर प्राप्त करने के लिए पढ़ा जाता है और दूसरा डेटा प्राप्त करने के लिए दूसरा पढ़ा जाता है)। ।

इस सी कोड मैं का उपयोग कर सी #/नकल करने की कोशिश कर रहा हूँ नेट है:

struct header 
{ 
    char id[2]; 
    char toname[12]; 
    char fromname[12]; 
    char routeto[6]; 
    char routefrom[6]; 
    char flag1; 
    char flag2; 
    char flag3; 
    char flag4; 
    char cycl[4]; 
    unsigned short len; 
}; 

मैं के साथ इस सी # आए हैं:

struct header header; /* 1-byte aligned structure (48 bytes) */ 
char *data; 

FILE* fp = fopen("flatfile", "r"); 
while (!feof(fp)) 
{ 
    fread(&header, 48, 1, fp); 
    /* Read header.length number of bytes to get the data. */ 
    data = (char*)malloc(header.length); 
    fread(data, header.length, 1, fp); 
    /* Do stuff... */ 
    free(data); 
} 

इस शीर्ष लेख की सी संरचना है सी हेडर का प्रतिनिधित्व करने के लिए ऑब्जेक्ट:

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi, Size = 48)] 
class RouterHeader 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 
    char[] Type; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] 
    char[] To; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] 
    char[] From; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 
    char[] RouteTo; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 
    char[] RouteFrom; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 
    char[] Flags; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 
    char[] Cycle; 

    UInt16 Length; 
} 
+0

आपका हेडर कैसा दिखता है? –

+1

सी की फ्रेड फ़ाइल i/o के समतुल्य [एसी # समकक्ष के संभावित डुप्लिकेट) (http://stackoverflow.com/questions/1935851/ac-equivalent-of-cs-fread-file-io) –

+0

मैंने पोस्ट संपादित किया है हेडर संरचना को शामिल करने के लिए। –

उत्तर

0

link Hans Passant provided का जवाब है। मैं उसे श्रेय दूंगा, लेकिन मुझे यकीन नहीं है कि जवाब के बजाए टिप्पणी के रूप में पोस्ट करने के बाद क्या करना है।

0

वैकल्पिक रूप से, आप एक हेड बनाने के लिए यूनियन जैसी संरचना का उपयोग करने का प्रयास कर सकते हैं आर संरचना जिसे आप एक बार में पढ़ सकते हैं (उदाहरण के लिए उचित लंबाई की स्ट्रिंग के रूप में), लेकिन जब आप उस संरचना से जानकारी प्राप्त करते हैं तो व्यक्तिगत फ़ील्ड को संदर्भित करने में सक्षम होते हैं।

आप उस प्रकार की चीज़ here प्राप्त करने के लिए स्ट्रक्चरलाइट्स और फील्डऑफसेट्स का उपयोग करने पर कुछ और विवरण प्राप्त कर सकते हैं।

& पढ़ने पर कुछ और चर्चा है C# here के साथ बाइनरी फाइलें लिखना। यह सुझाव दिया जाता है कि कई क्षेत्रों में पढ़ने के लिए बाइनरी रीडर का उपयोग आमतौर पर छोटे (< 40) फ़ील्ड की संख्या के लिए अधिक कुशल होता है।

2

ठीक है, आप लम्बाई पढ़ने के लिए Stream.Read पर एक कॉल का उपयोग कर सकते हैं (हालांकि आपको यह सुनिश्चित करने के लिए रिटर्न वैल्यू की जांच करने की आवश्यकता है कि आपने जो कुछ भी पूछा है उसे पढ़ लिया है; आपको यह सब एक ही समय में नहीं मिल सकता है) और उसके बाद डेटा को बाइट सरणी में प्राप्त करने के लिए Stream.Read पर एक और कॉल (फिर से, जब तक आप कुछ भी पढ़ नहीं लेते) लूपिंग करें। एक बार यह स्मृति में हो जाने के बाद, आप अपनी संरचना (या कक्षा) का उदाहरण बनाने के लिए बफर से उचित बाइट चुन सकते हैं।

व्यक्तिगत रूप से मैं StructLayout का उपयोग करने के बजाय स्पष्ट रूप से यह सब करना पसंद करता हूं - बाद वाला हमेशा मुझे कुछ हद तक भंगुर महसूस करता है।

0

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

यह भी विचार करें: यदि आपको संस्करण 2.0 लिखना है, तो संरचना के अंत में एक नया फ़ील्ड जोड़ा गया है? आपके उदाहरण में, आपको एक नई संरचना को परिभाषित करने की आवश्यकता होगी, और आप दोनों परिभाषाओं के साथ फंस जाएंगे। यदि आप कोड में पढ़/लिखना चुनते हैं, तो आप सशर्त रूप से नए तत्व को पढ़कर एक ही कोड के साथ दोनों का समर्थन कर सकते हैं।

0

मेरा झुकाव डेटा को एक सरणी में पढ़ना होगा, और उसके बाद डेटा ऑब्जेक्ट को उचित रूप से इकट्ठा करना होगा, बदलावों का उपयोग करके शब्दों, लडवर्ड इत्यादि को संभालने के लिए जोड़ना होगा।मेरे पास उस तरह की चीज़ को संभालने के लिए कुछ उपयोगिता वर्ग हैं।