2012-02-29 75 views
13

मुझे स्कैनर के साथ अजीब व्यवहार है। यह Scanner(FileInputStream) कन्स्ट्रक्टर का उपयोग करते समय मैं उपयोग की जा रही फ़ाइलों के एक विशेष सेट के साथ काम करूंगा, लेकिन यह Scanner(File) कन्स्ट्रक्टर के साथ नहीं होगा।जावा स्कैनर (फ़ाइल) गलत व्यवहार, लेकिन स्कैनर (FIleInputStream) हमेशा उसी फ़ाइल के साथ काम करता है

केस 1: Scanner(File)

Scanner s = new Scanner(new File("file")); 
while(s.hasNextLine()) { 
    System.out.println(s.nextLine()); 
} 

परिणाम: कोई उत्पादन

केस 2: Scanner(FileInputStream)

Scanner s = new Scanner(new FileInputStream(new File("file"))); 
while(s.hasNextLine()) { 
    System.out.println(s.nextLine()); 
} 

परिणाम: फ़ाइल सामग्री कंसोल के लिए आउटपुट।

इनपुट फ़ाइल एक जावा फ़ाइल वाली एक जावा फ़ाइल है।

मैं प्रोग्राम के रूप में जाँच की डबल (जावा में) है कि:

  • फ़ाइल मौजूद है,
  • पढ़ी जा सकती है,
  • और एक गैर शून्य फ़ाइल आकार है।

आमतौर पर Scanner(File) इस मामले में मेरे लिए काम करता है, मुझे यकीन नहीं है कि यह अब क्यों नहीं है।

+0

क्या फ़ाइल करता तथ्यों में, करने के लिए परीक्षण को बदलने? – Dan675

+0

और क्या यह एकमात्र कोड है, या क्या अन्य चीजें इसके आसपास हो रही हैं? यह स्निपेट अपूर्ण लगता है, क्योंकि कम से कम कुछ अपवाद हैंडलिंग हो रही है। क्या आप हमें पूरा कोड प्रदान कर सकते हैं? – haylem

+0

दिलचस्प सवाल। कृपया अपनी वास्तविक कोड और अपनी फ़ाइल के साथ एक पेस्टबिन पोस्ट करें। साथ ही, आपके सिस्टम पर 'Charset.defaultCharset() 'का आउटपुट क्या है? – Perception

उत्तर

7

hasNextLine() कॉल findWithinHorizon() जो बारी-बारी findPatternInBuffer() कहता है, एक लाइन टर्मिनेटर चरित्र पैटर्न .*(\r\n|[\n\r\u2028\u2029\u0085])|.+$

अजीब बात के रूप में परिभाषित के लिए एक मैच खोज है कि दोनों तरीकों के साथ एक स्कैनर (FileInputStream साथ या फ़ाइल के माध्यम से), findPatternInBuffer रिटर्न के निर्माण के लिए है एक सकारात्मक मिलान अगर फ़ाइल में (फ़ाइल आकार से स्वतंत्र रूप से) उदाहरण के लिए 0x0A लाइन टर्मिनेटर है; लेकिन इस मामले में फ़ाइल में एसीआईआई (यानी> = 7 एफ) से एक वर्ण होता है, फ़ाइल का उपयोग करते समय FileInputStream सत्य का उपयोग करते हुए सत्य लौटाता है।

बहुत ही सरल परीक्षण का मामला:

# hexedit file 
00000000 61 0A 80            a.. 

# java Test.java 
using File: false 
using FileInputStream: true 
परीक्षण जावा कोड में

:

जो सिर्फ चार "एक"

# hexedit file  
00000000 61 0A            a. 

# java Test.java 
using File: true 
using FileInputStream: true 

अब फ़ाइल hexedit साथ करने के लिए संपादित होता है एक फ़ाइल बनाने के प्रश्न में पहले से कुछ भी नहीं है:

import java.io.*; 
import java.lang.*; 
import java.util.*; 
public class Test { 
    public static void main(String[] args) { 
     try { 
       File file1 = new File("file"); 
       Scanner s1 = new Scanner(file1); 
       System.out.println("using File: "+s1.hasNextLine()); 
       File file2 = new File("file"); 
       Scanner s2 = new Scanner(new FileInputStream(file2)); 
       System.out.println("using FileInputStream: "+s2.hasNextLine()); 
     } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 
} 

SO, यह पता चला है कि यह एक वर्णमाला मुद्दा है।

Scanner s1 = new Scanner(file1, "latin1"); 

हम पाते हैं::

# java Test 
using File: true 
using FileInputStream: true 
+0

दिलचस्प। 'स्कैनर' contrustors को देखते समय वे सभी निर्दिष्ट नहीं होने पर डिफ़ॉल्ट वर्णसेट मानते हैं, फिर भी जब आप इंगित करते हैं तो रनटाइम पर कोई अंतर होता है। शायद चैनल आंतरिक रूप से इस्तेमाल किया जा सकता है शायद एक अलग, एक स्तर गहरा? मैं सोच रहा हूँ ... मुझे मौका मिलने पर जांचने की कोशिश करेंगे। – haylem

5

Oracle/Sun JDK's 1.6.0_23 implementation of Scanner को देख से, Scanner(File) निर्माता एक FileInputStream, जो meant for raw binary data है invokes।

यह एक कन्स्ट्रक्टर या किसी अन्य का आह्वान करते समय उपयोग की जाने वाली बफरिंग और पार्सिंग तकनीक में एक अंतर को इंगित करता है, जो hasNextLine() पर कॉल पर आपके कोड को सीधे प्रभावित करेगा।

Scanner(InputStream) का उपयोग करता है एक InputStreamReader जबकि Scanner(File) एक InputStream एक ByteChannel के लिए पारित का उपयोग करता है (और शायद एक कूद में पूरी फ़ाइल पढ़ता है, इस प्रकार कर्सर को आगे बढ़ाने के लिए, अपने मामले में)।

+0

बहुत रोचक जानकारी, –

+2

साझा करने के लिए धन्यवाद, जावा (फ़ाइल) और जावा (FileInputStream) के लिए अनुबंध वही पढ़ता है, इसलिए उन्हें एपीआई उपयोगकर्ता के दृष्टिकोण से वही व्यवहार करना चाहिए। मैंने इस मुद्दे के बिना जावा (फ़ाइल) का उपयोग किया है। – kashiko

+0

यानिक: धन्यवाद, यह एक दिलचस्प सवाल है। लेकिन इसके लिए और भी बहुत कुछ लगता है ... (फिर भी, सामान जो आप कभी भी जेडीके के कोड से खोद सकते हैं ... एक "क्या ??" क्षण था जब मैंने देखा कि 'ऐरेलिस्ट' की कई परिभाषाएं हैं, उदाहरण के लिए (और नहीं, वे बिल्कुल समान नहीं हैं) – haylem