2011-06-23 17 views
6

मैं एक फ़ाइल से ब्लॉक पढ़ने की कोशिश कर रहा हूं और मुझे कोई समस्या है।अज्ञात आकार फ़ाइल से पढ़ने के लिए बफर का उपयोग

char* inputBuffer = new char[blockSize] 
while (inputFile.read(inputBuffer, blockSize)) { 
    int i = inputFile.gcount(); 
//Do stuff 
} 

मान लीजिए हमारे ब्लॉक आकार 1024 bytes है, और फ़ाइल 24,3 KiB है। 23 वें ब्लॉक पढ़ने के बाद, 0,3 KiB पढ़ने के लिए छोड़ दिया जाएगा। मैं भी 0,3 KiB पढ़ना चाहता हूं, वास्तव में मैं gcount() का उपयोग करता हूं, इसलिए मैं जान सकता हूं कि बफर में से कितने read(...) संशोधित (यदि यह कम है)।
लेकिन जब यह 24 वें ब्लॉक तक पहुंचता है, read(...) एक मान देता है जैसे प्रोग्राम लूप में प्रवेश नहीं करता है, जाहिर है क्योंकि फ़ाइल में शेष अपठित बाइट्स का आकार बफर आकार से कम है। मुझे क्या करना चाहिए?

उत्तर

3

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

bool okay=true; 
while (okay) { 
    okay = inputFile.read(inputBuffer, blockSize); 
    int i = inputFile.gcount(); 
    if(i) { 
     //Do stuff 
    } 
} 

संपादित करें: चूंकि मेरा उत्तर स्वीकार कर लिया गया है, इसलिए मैं इसे यथासंभव उपयोगी बनाने के लिए संपादित कर रहा हूं। यह पता चला है कि मेरा बूल ठीक है अनावश्यक है (फेरोशेहन का जवाब देखें)। इनपुटफाइल के मूल्य का परीक्षण करना बेहतर है, यह भी लाभ है कि अगर आप ठीक से नहीं खुलते हैं तो आप लूप में प्रवेश करने से बच सकते हैं। तो मुझे लगता है कि यह इस समस्या का कैननिकल समाधान है;

inputFile.open("test.txt", ios::binary); 
while (inputFile) { 
    inputFile.read(inputBuffer, blockSize); 
    int i = inputFile.gcount(); 
    if(i) { 
     //Do stuff 
    } 
} 

अब पिछली बार जब आप सामान करो //, मैं blocksize की तुलना में कम, मामला उस फ़ाइल blocksize की एक बहु बाइट लंबा होने में छोड़कर किया जाएगा।

कोनराड रूडोल्फ का जवाब here भी अच्छा है, इसका लाभ यह है कि .gcount() केवल लूप के बाहर एक बार बुलाया जाता है, लेकिन नुकसान यह है कि डुप्लिकेशंस से बचने के लिए इसे एक अलग फ़ंक्शन में डेटा प्रसंस्करण की आवश्यकता होती है ।

+0

आपको "okay = inputFile.read (...)" के बाद एक (ठीक है) शामिल करना चाहिए ताकि आप आश्वस्त कर सकें कि प्रोग्राम कभी भी अमान्य डेटा के साथ काम नहीं करेगा। ऐसा करें इसलिए मैं इसे एक स्वीकृत उत्तर के रूप में चिह्नित करता हूं। – Erandros

+0

@ एन्डंडोस, कोई काम नहीं करेगा क्योंकि तब आप स्क्वायर 1 पर वापस आ गए हैं - आप अंतिम सब्सक्राइब किए गए ब्लॉक को संसाधित नहीं करेंगे! इसके बजाय शायद अगर (i) जोड़ें, तो डेटा होने पर केवल तभी सामग्री करें। –

+0

आप सही हैं। मुझे अभी भी लगता है कि "अगर (lessThanBufferSizeFlag) होना चाहिए"। मुझे नहीं पता कि उस ध्वज मूल्य को कैसे प्राप्त किया जाए। – Erandros

1

लेकिन जब 24 ब्लॉक तक पहुँचता है, पढ़ने के लिए (...) ऐसी है कि कार्यक्रम पाश में प्रवेश नहीं करता, स्पष्ट रूप से, क्योंकि फ़ाइल में शेष अपठित बाइट्स के आकार बफर से भी कम है एक मान देता है आकार।

ऐसा इसलिए है क्योंकि आपका लूप गलत है। आप क्या करना चाहिए:

while(!inputFile) { 
    std::streamsize numBytes = inputFile.readsome(inputBuffer, blockSize); 
//Do stuff 
} 

सूचना readsome बजाय read का उपयोग।

+0

वह लूप गलत है?यह 100 के प्रतिनिधि व्यक्ति विपरीत कहता है: http://stackoverflow.com/questions/6444876/c-reading-buffer-size/6444962#6444962 हालांकि मैं इसे पढ़ने की कोशिश करूंगा। – Erandros

+1

@Erandros: वह यह भी कहता है कि पढ़ने की स्थिति के अंदर पढ़ने को "अधिक पठनीय" है, जो कुछ मैं लड़ूंगा। वास्तविक कार्य करने वाली हालत बयान सी/सी ++ में एक स्थापित मुहावरे हो सकता है, लेकिन यह जरूरी नहीं है कि यह एक अच्छा या पठनीय हो। –

+0

मैं "अधिक पठनीय" मुद्दे पर सहमत हूं। लेकिन, अगर मैं पढ़ता हूं और विफल रहता हूं तो क्या होता है? मैं भ्रष्ट डेटा के साथ सामान कर रहा हूँ। यह सुनिश्चित करना कि यह कभी नहीं होगा, जबकि उस समय का उछाल था। – Erandros

3

समाधान @ कोनराड रुडॉल्फ का उल्लेख धारा वस्तु के लिए स्वयं जांचना है क्योंकि इसमें ईओएफ और त्रुटि की स्थिति की जांच शामिल है। inputFile.read() धारा देता है जो अपने आप inputfile ताकि आप की तरह

while(inputFile.read()) 

लिख सकते हैं लेकिन यह हमेशा काम नहीं करेगा। जिस मामले में यह विफल रहता है वह आपका मामला है। एक उचित समाधान

char* inputBuffer = new char[blockSize] 
while (inputFile) 
{ 
    inputFile.read(inputBuffer, blockSize); 
    int count = inputFile.gcount(); 
    //Access the buffer until count bytes 
    //Do stuff 
} 

मुझे लगता है कि यह समाधान था कि @ कोनराड रुडॉल्फ का मतलब उनके पद में था। मेरे पुराने सीपीपी अनुभव से मैं उपरोक्त की तरह कुछ भी करूंगा।

+0

यह भी काम करता है। – Erandros

+0

मैं वास्तव में सहमत हूं, यह मेरे समाधान पर एक सुधार है, इसलिए +1 अच्छी तरह से किया गया। –

+0

लूप के बाद, मुझे केवल एक ही (बहुत मामूली) लाभ है कि मुझे केवल 'gcount' की जांच करने की आवश्यकता है (लूप के अंदर यह हमेशा' ब्लॉक आकार 'के बराबर होगा)। और मैं वास्तव में अनावश्यक परिचालन करने से नापसंद करता हूं, भले ही वे सस्ते हों। उस ने कहा, जैसे ही बफर संसाधित हो जाता है, उतना ही आपका समाधान बेहतर होता है (= एक कथन से अधिक)। –