2011-08-21 21 views
6

मैं एक बड़ी फाइल लिखने की कोशिश कर रहा हूं, लेकिन एक समस्या में भाग गया।सी ++ के साथ 4 जीबी फ़ाइल में डेटा कैसे लिखें?

मैं लिखने के लिए जगह खोजने के लिए लंबे समय तक उपयोग करता हूं, लेकिन 4,2 जीबी से अधिक फ़ाइल नहीं लिख सकता। मैं क्या भूल गया?

अधिक विवरण: मैं 4Gb-फ़ाइल को खोलने:

ifstream ifs(db_name.c_str(), ios_base::binary); 
if (!ifs) 
    throw Bad_archive(); 
ifs.read(as_bytes(seg_size), sizeof(int)); 
ifs.read(as_bytes(last_idx), sizeof(int)); 
ifs.read(as_bytes(free_segs), sizeof(int)); 
if (free_segs > 0) 
{ 
    long long seek_g = 3 * sizeof(int) + (long long)last_idx * seg_size; 
    ifs.seekg(seek_g, ios_base::beg); 
    for (int i = 0; i < free_segs; i++) 
    { 
     int tmp = 0; 
     ifs.read(as_bytes(tmp), sizeof(int)); 
     free_spaces.push_back(tmp); 
    } 
} 
ifs.close(); 

उसके बाद, मैं 400MB-फ़ाइल है, जो मैं db में जोड़ना चाहते हैं पढ़ें। और लिखने (यहाँ शॉर्ट कोड है):

// write object 
ofstream ofs(db_name.c_str(), ios_base::binary | ios_base::in | ios_base::ate); 
for (int i = 0; ; i++) 
{ 
    // set stream position 
    long long write_position = sizeof(int) * 3; 

    ... 

    write_position += (long long) seg_size * last_idx; 
    ofs.seekp(write_position, ios::beg); 

      ... 

    // write sizeof object 
    if (i == 0) 
     ofs.write(as_bytes(object_size), sizeof(object_size)); 
    else 
    { 
     int null = 0; 
     ofs.write(as_bytes(null), sizeof(null)); 
    } 

    // write data 
    for (int j = 0; j < (seg_size - sizeof(int) * 2); j++) 
    { 
     ofs.write(as_bytes(obj_content[j + i * (seg_size - sizeof(int) * 2)]), 
     sizeof(char)); 

    } 
    if (write_new_seg) 
     last_idx++; 

    ... 

    ofs.write(as_bytes(cont_seg), sizeof(cont_seg)); 
} 
ofs.close(); 

उसके बाद, मैं db जानकारी को बचाने:

if (last_idx == 0) 
{ 
    ofstream ofs(db_name.c_str()); 
    ofs.close(); 
} 
ofstream ofs(db_name.c_str(), ios_base::binary | ios_base::in | 
      ios_base::out | ios_base::ate); 
long long seek_p = 0; 
ofs.seekp(seek_p, ios_base::beg); 
ofs.write(as_bytes(seg_size), sizeof(seg_size)); 
ofs.write(as_bytes(last_idx), sizeof(last_idx)); 
ofs.write(as_bytes(free_segs), sizeof(free_segs)); 
ofs.close(); 

लेकिन इस कोड काम करता है:

ofstream ofs2("huge2"); 
ofs2.close(); 
ofstream ofs("huge2", ios_base::in | ios_base::ate); 
long long sp = 10000000000; 
ofs.seekp(10000000000, ios_base::beg); 

ofs.write(as_bytes(sp), sizeof(sp)); 

ofs.close(); 
+0

आप हमेशा एक लूप में खोज सकते हैं और जिस बिंदु पर आप चाहते हैं उसे अग्रिम कर सकते हैं लेकिन गैर गठबंधन ऑफसेट के लिए ट्रैक रखना मुश्किल हो जाता है। –

+0

मैं कोशिश करूंगा। Thanx – bluebyte

+0

कई सी ++ स्ट्रीम कार्यान्वयन पिछले शताब्दी में फंस गए हैं। जब 4 गीगाबाइट सभी के लिए पर्याप्त था। Char_traits :: pos_type को 64 अंगुलियों के साथ गिनने के लिए अद्यतन करना इतना आसान नहीं है, जो मौजूदा कोड को तोड़ देता है। Int के बारे में बात करते हुए उल्लिखित उत्तर स्पष्ट करता है। –

उत्तर

4
fseeko64 (Filename, 0, SEEK_END); 
    long size = ftello64 (Filename); 
    fclose (Filename); 

बड़ी फ़ाइलों तक पहुँचने के लिए, fseek नहीं किया जा सकता है, बजाय fseeko64 के लिए जाना है();

0

कई filesystems फ़ाइलों का समर्थन नहीं करते 4 जीबी से बड़ा इसके अतिरिक्त, आपको यह मानना ​​चाहिए कि आपके int प्रकार में ऐसी सीमा हो सकती है जो 2^32 पर समाप्त हो, यानी 4.2 9 4 9 7e + 09।

+1

1. मेरे पास एनटीएफएस है। 2. मैं int के बारे में पता है। मैं चर के लिए लंबे समय तक उपयोग करता हूं जिसे इस मामले में ओवरफिल किया जा सकता है। – bluebyte

+0

हालांकि यह वास्तव में एक स्पष्टीकरण नहीं है। सी मानक को कम से कम 8byte चौड़ाई वाले प्रकारों की आवश्यकता होती है ताकि वे उनमें से किसी एक का उपयोग करके एक फ़ंक्शन जोड़ सकें। इसके अलावा ऐसे फाइल सिस्टम हैं जो 32 एमबी से अधिक की अनुमति नहीं देते हैं, इसलिए आज बहुत बड़ा मूल्य होने की समस्या पहले से मौजूद है .. – Voo

+0

@Voo: हां, निश्चित रूप से इस समस्या में _always_ अस्तित्व में है, जब तक कुछ ऐतिहासिक फाइल सिस्टम नहीं था इसके बारे में पता है कि एक बार अनंतता आकार की फाइलों की अनुमति है। –

1

Win32 पर _lseeki64() नामक एक फ़ंक्शन है, और lseek64() पर * nix। हालांकि, iostream लाइब्रेरी उन्हें सीधे लपेटती नहीं है, आपको फ़ाइल डिस्क्रिप्टर को किसी भी तरह से पुनर्प्राप्त करना होगा, और बफरिंग के बारे में कुछ करना होगा।

+0

असल में यदि वह पहले से ही मंच विशिष्ट कोड का उपयोग कर रहा है, तो वह विंडोज के तहत 'ओवरलैप्ड' संरचना के साथ '(लिखें | पढ़ें) फ़ाइल' का उपयोग कर सकता है। यह 8byte ऑफसेट का समर्थन करता है हालांकि आप एक बार में केवल 4 जीबी लिख सकते हैं। मुझे लगता है कि कहीं भी POSIX में परिभाषित कुछ समान आरामदायक कार्य है। – Voo

0

लिनक्स यहाँ के लिए एक अच्छी सारांश है: RedHat लक्ष्यीकरण RHEL से

http://www.suse.de/~aj/linux_lfs.html

और अधिक विशिष्ट विस्तार, इन समस्याओं 64-बिट फ़ाइलों आकार तक पहुँचने 32-बिट अनुप्रयोगों के लिए आम तौर पर कर रहे हैं।

http://people.redhat.com/berrange/notes/largefile.html

विकिपीडिया वास्तव में Large File Support पर एक artile लेकिन वास्तव में है कि जानकारीपूर्ण नहीं है।

संबंधित मुद्दे