2010-09-29 13 views
7

मेरे पास एक फ़ाइल है जिसमें लगभग 200,000 लंबे मूल्य हैं जिन्हें मैं जितनी जल्दी हो सके पढ़ना चाहता हूं []। यह एक एंड्रॉइड ऐप के लिए है; फ़ंक्शन कॉल धीमे होते हैं (इसलिए "फॉर" लूप के साथ एक समय में लंबे समय तक पढ़ने में शामिल कुछ भी सुपर धीमा हो जाएगा) और मुझे तेज़ी से लोड होने की आवश्यकता है। मैं क्या उपयोग कर सकता हूँ जो कुछ भी मैं देखता हूं वह केवल बाइट्स को तेज़ी से पढ़ता है।फ़ाइल से लंबे [] पढ़ने के लिए सबसे तेज़ तरीका?

मैंने पहले एनआईओ पैकेज से ByteBuffer और FileChannel का उपयोग किया है और यह फ़ाइलों से मूल्यों के सरणी लोड करने का एक तेज़ तरीका प्रतीत होता है। हालांकि, मैं लंबे समय तक डेटा पढ़ने के लिए इसका उपयोग कैसे कर सकता हूं []। मैंने लांगबफर के रूप में एक लंबा [] लपेटने की कोशिश की है, लेकिन मैं किसी भी तरह से फ़ाइल से डेटा को लॉन्गबफर में नहीं खिला सकता हूं।

संपादित करें: मैं जिस भी विधि का उपयोग करता हूं, मुझे का उपयोग long[] सरणी पर अंत में करने में सक्षम होना चाहिए।

+0

मुझे यकीन नहीं है कि ये कैसे मदद करते हैं। मैं नहीं देख सकता कि वे मेरे प्रश्न का उत्तर कैसे देते हैं। – memcom

उत्तर

3

डाली एक byte[] का कोई उपाय नहीं एक long[] में नहीं है। हालांकि, आप में सामग्री को पढ़ने के लिए FileChannel का उपयोग करने का प्रयास कर सकते हैं और फिर LongBufferByteBuffer.asLongBuffer के माध्यम से प्राप्त कर सकते हैं, जिससे आप long[]LongBuffer.array() के माध्यम से प्राप्त कर सकते हैं।

आप फ़ाइल के MappedByteBuffer प्राप्त करने के लिए FileChannel.map भी आजमा सकते हैं। यह FileChannel.read के माध्यम से जाने से तेज़ हो सकता है।

इस आप एक FileChannel उपयोग करने के लिए एक ByteBuffer में सामग्री पढ़ने के लिए और फिर इसे अंदर long रों का उपयोग, ByteBuffer.getLong(index) का उपयोग कर की कोशिश कर सकते काम नहीं करता है।


एक वैकल्पिक समाधान। (कोई :-)

byte[] byteArray = new byte[longCount * 8]; 
FileInputStream fis = new FileInputStream("lotsoflongs"); 
fis.read(byteArray); 
fis.close(); 
for (int i = 0; i < longCount; i += 8) 
    longArray[i >> 3] = ((long) byteArray[0+i]  << 56) + 
         ((long)(byteArray[1+i] & 255) << 48) + 
         ((long)(byteArray[2+i] & 255) << 40) + 
         ((long)(byteArray[3+i] & 255) << 32) + 
         ((long)(byteArray[4+i] & 255) << 24) + 
           ((byteArray[5+i] & 255) << 16) + 
           ((byteArray[6+i] & 255) << 8) + 
           ((byteArray[7+i] & 255) << 0); 

पाश में विधि-कॉल मैं अब कुछ समाधान बेंचमार्क है, और यह एक कर के सबसे तेज़ तरीका हो रहा है। साथ ही, ध्यान दें कि fis.read(byteArray) में पढ़ने वाले वास्तविक बाइट बाइटएरे के वास्तविक आकार से कम हो सकते हैं। इस प्रकार, यदि यह ठीक से किया जाना चाहिए, तो आपको इसे एक लूप में रखना होगा जो तब तक पुनरावृत्त हो जाता है जब तक कि सभी बाइट्स पढ़े न जाएं।

+0

मुझे लंबे समय तक [] की तरह लंबे समय तक उपयोग करने में सक्षम होना चाहिए [] Arrays.binarySearch – memcom

+0

के साथ इसका उपयोग करके लंबे समय तक 'सूची' को लागू करने के बारे में, बाइट-सरणी द्वारा समर्थित, और Collections.binarySearch का उपयोग करें? – aioobe

+0

मुझे यकीन नहीं है कि इसका मतलब क्या है? मैं ऐसी सूची वस्तु कैसे बनाऊंगा? – memcom

1

DataInputStream का उपयोग करने का प्रयास करें। चूंकि आप फ़ाइल की लंबाई आसानी से पा सकते हैं, आप यह भी जानते हैं कि इसमें कितने तत्व हैं (फाइलसाइज/8 बाइट)।

DataInputStream dataStream = new DataInputStream(inputStream); 

long count = filesize/8; 
long[] longArray = new long[count]; 

for(int i=0;i<count;i++) 
    longArray[i] = dataStream.getLong(); 

मान लीजिए कि आपको एक विचार देने के लिए पर्याप्त होना चाहिए।

+0

ओपी ने एक लूप में एक समय में एक लंबे समय तक पढ़ने से इंकार कर दिया। – aioobe

+0

@aioobe: आप लॉन्गबफर के लिए बाइनरी खोज के अपने संस्करण को क्यों लागू नहीं करते हैं? काफी आसान होना चाहिए, और फिर आप कर रहे हैं। :-) – mreichelt

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