2013-01-21 27 views
17

मेरे पास लंबी फ़ाइल है जिसे मुझे पार्स करने की आवश्यकता है। क्योंकि यह बहुत लंबा है, मुझे इसे खंड से अलग करने की ज़रूरत है। मैंने यह कोशिश की:जावास्क्रिप्ट फ़ाइल रीडर - भाग में लंबी फ़ाइल को पार्सिंग

function parseFile(file){ 
    var chunkSize = 2000; 
    var fileSize = (file.size - 1); 

    var foo = function(e){ 
     console.log(e.target.result); 
    }; 

    for(var i =0; i < fileSize; i += chunkSize) 
    { 
     (function(fil, start) { 
      var reader = new FileReader(); 
      var blob = fil.slice(start, chunkSize + 1); 
      reader.onload = foo; 
      reader.readAsText(blob); 
     })(file, i); 
    } 
} 

इसे चलाने के बाद मैं कंसोल में केवल पहला हिस्सा देखता हूं। अगर मैं कुछ div में jquery संलग्न करने के लिए 'console.log' को बदलता हूं तो मुझे उस div में केवल पहला खंड दिखाई देता है। अन्य हिस्सों के बारे में क्या? इसे कार्यशील कैसे करें?

उत्तर

6

slice का दूसरा तर्क वास्तव में अंत बाइट है।

function parseFile(file){ 
    var chunkSize = 2000; 
    var fileSize = (file.size - 1); 

    var foo = function(e){ 
     console.log(e.target.result); 
    }; 

    for(var i =0; i < fileSize; i += chunkSize) { 
     (function(fil, start) { 
      var reader = new FileReader(); 
      var blob = fil.slice(start, chunkSize + start); 
      reader.onload = foo; 
      reader.readAsText(blob); 
     })(file, i); 
    } 
} 

या आप आसान इंटरफेस के लिए इस BlobReader उपयोग कर सकते हैं:

BlobReader(blob) 
.readText(function (text) { 
    console.log('The text in the blob is', text); 
}); 

अधिक जानकारी:

आपका कोड कुछ ऐसा दिखाई देगा
+0

क्या लूप विश्वसनीय है? मैं 'फाइल रीडर' एपीआई के बजाय नया हूं लेकिन मुझे लगता है कि यह असीमित है। 'लूप' समाप्त होने के बाद हम कैसे सुनिश्चित कर सकते हैं कि पूरी फ़ाइल को पूरी तरह से संसाधित किया गया है? – alediaferia

36

FileReader एपीआई असीमित है इसलिए आपको block कॉल के साथ इसे संभालना चाहिए। एक for loop चाल नहीं करेगा क्योंकि यह अगले पढ़ने को पढ़ने से पहले प्रत्येक पढ़ने को पूरा करने की प्रतीक्षा नहीं करेगा। यहां एक कामकाजी दृष्टिकोण है।

function parseFile(file, callback) { 
    var fileSize = file.size; 
    var chunkSize = 64 * 1024; // bytes 
    var offset  = 0; 
    var self  = this; // we need a reference to the current object 
    var chunkReaderBlock = null; 

    var readEventHandler = function(evt) { 
     if (evt.target.error == null) { 
      offset += evt.target.result.length; 
      callback(evt.target.result); // callback for handling read chunk 
     } else { 
      console.log("Read error: " + evt.target.error); 
      return; 
     } 
     if (offset >= fileSize) { 
      console.log("Done reading file"); 
      return; 
     } 

     // of to the next chunk 
     chunkReaderBlock(offset, chunkSize, file); 
    } 

    chunkReaderBlock = function(_offset, length, _file) { 
     var r = new FileReader(); 
     var blob = _file.slice(_offset, length + _offset); 
     r.onload = readEventHandler; 
     r.readAsText(blob); 
    } 

    // now let's start the read with the first block 
    chunkReaderBlock(offset, chunkSize, file); 
} 
+2

यह शानदार है। बिना किसी समस्या के विशाल 3 जीबी + फाइलें पढ़ना। छोटे खंड आकार हालांकि थोड़ा धीमा बनाता है। – bryc

+0

वेब श्रमिक/ड्रैगन्रॉप का उपयोग करके मज़े के लिए इसका उपयोग करके एक सीआरसी 32 कैलक्यूलेटर लिखा। http://jsfiddle.net/9xzf8qqj/ – bryc

+2

मेरे लिए भी बड़ी फ़ाइलों के लिए काम किया। हालांकि, बड़ी फ़ाइलों (> 9 जीबी) के लिए, मैंने 'evt.target.result.length' द्वारा 'ऑफसेट' को बढ़ाने में पाया ** ** मेरी फ़ाइल को दूषित कर रहा था! मेरा त्वरित समाधान इसके बजाय 'chunkSize' द्वारा इसे बढ़ाना था। मुझे यकीन नहीं है कि यह एक एफएस मुद्दा है (मैं उबंटू पर हूं) या कुछ और, लेकिन अगर आप ऑफसेट + = चंकसाइज 'करते हैं तो यह किसी भी फाइलसाइज के लिए ठीक काम करता है। – user40171

1

मैं एक बहुत ही दिलचस्प विचार है कि शायद बहुत तेजी से है, क्योंकि यह शायद बहुत आसान भी एक ReadableByteStreamReader को ब्लॉब में परिवर्तित कर देंगे, क्योंकि आप हिस्सा आकार की तरह सामान को संभालने और ऑफसेट और फिर कर की जरूरत नहीं है के साथ आया था यह सब एक लूप में रिकर्सिव है - लेकिन केवल ब्लिंक के लिए काम करता है, एज इसे अगले संस्करण में प्राप्त करेगा

let pump = reader => reader.read() 
.then(({ value, done }) => { 
    if(done) return 
    console.log(value) // uint8array chunk 
    return pump(reader); 
}) 


window.blobToStream = blob => 
    fetch(URL.createObjectURL(blob)) 
    .then(res => pump(res.body.getReader()))