2015-05-16 7 views
6

आसानी से कच्चे बाइट-बाय-बाइट इनपुट रेंज/फॉरवर्ड रेंज/RandomAccessRange फ़ाइल से कैसे निर्माण करें?फ़ाइल से बाइट इनपुट रेंज

import std.file; 
auto data = cast(ubyte[]) read("filename"); 
// data is a full-featured random access range of the contents 

तो फ़ाइल बहुत बड़ी है कि उचित होने के लिए, आप एक स्मृति की कोशिश कर सकते:

उत्तर

13
file.byChunk(4096).joiner 

यह 4096-बाइट मात्रा में एक फ़ाइल पढ़ता है और lazily एक भी ubyte इनपुट रेंज में एक साथ हिस्सा मिलती है।

joinerstd.algorithm से है, तो आप यह पहली बार आयात करने के लिए होगा।

+2

मेरी इच्छा है कि मैं इस पांच बार ऊपर उठा सकता हूं, यह बहुत उपयोगी है और मुझे यह नहीं पता था! –

+0

@ AdamD.Ruppe इस सप्ताह के इस सप्ताह के लिए डी में एक अच्छा विषय की तरह लगता है! –

+0

कल्पना करें कि यह भविष्य में लपेटा गया है, और डेटा लोड होने पर आपको बस एक ईवेंट मिलता है ... अच्छी चीजें। – DejanLekic

7

एक फ़ाइल से एक कच्चे बाइट रेंज बनाने के लिए सबसे आसान तरीका है बस इसे स्मृति में सब ठीक पढ़ने के लिए है -mapped फ़ाइल http://dlang.org/phobos/std_mmfile.html और एक सरणी प्राप्त करने के लिए opSlice का उपयोग करें। चूंकि यह एक सरणी है, इसलिए आपको पूर्ण श्रेणी की सुविधाएं मिलती हैं, लेकिन चूंकि यह ऑपरेटिंग सिस्टम द्वारा मैप की गई मेमोरी है, इसलिए आप फ़ाइल को स्पर्श करते समय आलसी पढ़ते हैं।

एक सरल InputRange के लिए, वहाँ LockingTextReader फोबोस में (गैर-दस्तावेजी) है, या आप एक अपने आप को byChunk या यहाँ तक कि fgetc, सी समारोह की निर्माण कर सकता है। fgetc सबसे आसान लिखने के लिए होगा:

struct FileByByte { 
    ubyte front; 
    void popFront() { front = cast(ubyte) fgetc(fp); } 
    bool empty() { return feof(fp); } 
    FILE* fp; 
    this(FILE* fp) { this.fp = fp; popFront(); /* prime it */ } 
} 

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

एक आगे और न ही यादृच्छिक अभिगम सीमा है। जो बहुत सारे बफरिंग कोड के बिना धाराओं पर करने के लिए कठिन हैं और मुझे लगता है कि लिखने की कोशिश करने में गलती होगी - आम तौर पर, श्रेणियां सस्ता होनी चाहिए, अंतर्निहित कंटेनर विशेष रूप से समर्थन नहीं करता है।

संपादित करें: दूसरे उत्तर में एक गैर-बफरिंग तरीका है! https://stackoverflow.com/a/30278933/1457000 यह कमाल है।

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