2010-09-27 12 views
16

प्रश्न में फ़ाइल मेरे नियंत्रण में नहीं है। अधिकांश बाइट अनुक्रम मान्य यूटीएफ -8 हैं, यह आईएसओ -885 9 -1 (या एक अन्य एन्कोडिंग) नहीं है। मैं जितना संभव हो उतना अधिक जानकारी निकालने के लिए अपना सर्वश्रेष्ठ प्रयास करना चाहता हूं।जावा इनपुटस्ट्रीम में उन्हें बदलने के लिए अवैध यूटीएफ -8 बाइट अनुक्रमों का पता कैसे लगाएं?

फ़ाइल में कुछ अवैध बाइट अनुक्रम शामिल हैं, जिन्हें प्रतिस्थापन चरित्र के साथ प्रतिस्थापित किया जाना चाहिए।

यह एक आसान काम नहीं है, ऐसा लगता है कि इसे यूटीएफ -8 राज्य मशीन के बारे में कुछ जानकारी चाहिए।
UTF8ValidationFilter javadoc

वहाँ ऐसा ही कुछ उपलब्ध (व्यावसायिक रूप से या के रूप में मुफ्त सॉफ्टवेयर) है:

ओरेकल जो मैं क्या आवश्यकता है एक आवरण है?

धन्यवाद
-stephan

समाधान:

final BufferedInputStream in = new BufferedInputStream(istream); 
final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder(); 
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE); 
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 
final Reader inputReader = new InputStreamReader(in, charsetDecoder); 
+10

मुझे इससे नफरत है। सामग्री उत्पादकों को वैध सामग्री का उत्पादन करना चाहिए, उपभोक्ताओं को अनुमान लगाने और सही करने के लिए नहीं कहना चाहिए। इससे हमारे उद्योग में इतनी परेशानी हो रही है। – irreputable

उत्तर

12

java.nio.charset.CharsetDecoder आपको क्या चाहिए होता है। यह वर्ग विभिन्न प्रकार की त्रुटियों पर उपयोगकर्ता-परिभाषित क्रियाओं के साथ वर्णसेट डिकोडिंग प्रदान करता है (onMalformedInput() और onUnmappableCharacter() देखें)।

CharsetDecoder एक OutputStream को लिखते हैं, जो आपको एक InputStream में पाइप java.io.PipedOutputStream का उपयोग कर सकते हैं, प्रभावी रूप से फ़िल्टर किए गए InputStream बनाने।

+0

यह तेजी से सहायक था, धन्यवाद। – user85155

+0

@ हेनिंग - अगर मैं जानना चाहता हूं कि कौन सी रेखा खराब अक्षरों पर है? – Dejell

+1

@ डीजेल आप इनपुट में लाइनों को विभाजित कर सकते हैं, और प्रति पंक्ति त्रुटियों को पहचानने का प्रयास करें। –

0

बाइट ऑर्डर मार्क (यदि मौजूद है) को जांचने के लिए पहले कुछ बाइट्स को पढ़ने का एक तरीका होगा। बीओएम पर अधिक जानकारी: http://en.wikipedia.org/wiki/Byte_order_mark दिए गए यूआरएल में, आपको बीओएम बाइट्स की एक तालिका मिल जाएगी। हालांकि, एक समस्या यह है कि, यूटीएफ -8 को अपने 'हेडर' में बीओएम का उपयोग करने की आवश्यकता नहीं है। समस्या को हल करने का एक और तरीका पैटर्न पहचान द्वारा है (हर बार कुछ बाइट्स -8 बिट्स पढ़ें)। वैसे भी, यह जटिल समाधान है ..

+0

समस्या एक बीओएम नहीं था, यह पहले से ही हटा दिया गया था। एक BOMStripperInputStream चारों ओर तैरता है, जो यहां सहायता करता है: http://code.google.com/p/train-graph/source/browse/trunk/src/org/paradise/etrc/data/BOMStripperInputStream.java?r=31 – user85155

0

जो व्यवहार आप चाहते हैं वह InputStreamReader के लिए पहले से ही डिफ़ॉल्ट है। इसलिए इसे स्वयं निर्दिष्ट करने की कोई आवश्यकता नहीं है। यह पर्याप्त है:

final BufferedInputStream in = new BufferedInputStream(istream); 
final Reader inputReader = new InputStreamReader(in, StandardCharsets.UTF_8); 
संबंधित मुद्दे