كيفية تحويل القارئ إلى InputStream والكاتب إلى OutputStream؟

StackOverflow https://stackoverflow.com/questions/62241

  •  09-06-2019
  •  | 
  •  

سؤال

هل هناك طريقة سهلة لتجنب التعامل مع مشاكل ترميز النص؟

هل كانت مفيدة؟

المحلول

لا يمكنك حقًا تجنب التعامل مع مشكلات ترميز النص، ولكن هناك حلول موجودة:

تحتاج فقط إلى اختيار الترميز الذي تختاره.

نصائح أخرى

إذا كنت تبدأ باستخدام سلسلة، فيمكنك أيضًا القيام بما يلي:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))

حسنًا، يتعامل القارئ مع الأحرف ويتعامل InputStream مع البايتات.يحدد التشفير الطريقة التي تريد بها تمثيل الأحرف بالبايت، لذلك لا يمكنك تجاهل المشكلة حقًا.أما بالنسبة لتجنب المشاكل، رأيي هو:اختر مجموعة محارف واحدة (على سبيل المثال"UTF-8") والتزم به.

وفيما يتعلق بكيفية القيام بذلك فعليا، كما تمت الإشارة إليه، "الأسماء الواضحة لهذه الفئات هي ReaderInputStream و WriterOutputStream."من المستغرب"لم يتم تضمينها في مكتبة Java"على الرغم من أن الطبقات" المعاكسة "، قارئ الإدخال و OutputStreamWriter نكون متضمنة.

لذا، فقد توصل الكثير من الأشخاص إلى تطبيقاتهم الخاصة، بما في ذلك أباتشي كومنز آيو.اعتمادًا على مشكلات الترخيص، ربما ستتمكن من تضمين مكتبة commons-io في مشروعك، أو حتى نسخ جزء من الكود المصدري (القابل للتنزيل) هنا).

كما ترون، تنص وثائق كلا الفئتين على أنه "يتم التعامل مع جميع ترميزات مجموعة الأحرف المدعومة بواسطة JRE بشكل صحيح".

ملحوظة:يذكر تعليق على إحدى الإجابات الأخرى هنا هذا الخطأ.ولكن هذا يؤثر على أباتشي نملة فئة ReaderInputStream (هنا), لا الأباتشي كومنز آيو فئة ReaderInputStream.

لاحظ أيضًا أنه إذا كنت تبدأ بسلسلة، فيمكنك تخطي إنشاء StringReader وإنشاء InputStream في خطوة واحدة باستخدام org.apache.commons.io.IOUtils من كومنز آيو مثل ذلك:

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

بالطبع لا تزال بحاجة إلى التفكير في ترميز النص، ولكن على الأقل يتم التحويل في خطوة واحدة.

يستخدم:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

هذه الطريقة لا تتطلب تحويلاً مقدمًا إلى String ومن ثم الى byte[], ، الذي يخصص الكثير من ذاكرة الكومة، في حالة أن التقرير كبير.يتم تحويله إلى بايت أثناء قراءة الدفق، مباشرة من StringBuffer.

يستخدم CharSequenceInputStream من مشروع Apache Commons IO.

الأسماء الواضحة لهذه الفئات هي ReaderInputStream وWriterOutputStream.لسوء الحظ لم يتم تضمينها في مكتبة جافا.ومع ذلك، جوجل هو صديقك.

لست متأكدًا من أنه سيتغلب على جميع مشكلات ترميز النص، والتي تعتبر كابوسية.

هناك RFE، لكنه مغلق، لن يتم إصلاحه.

لا يمكنك تجنب مشاكل ترميز النص، ولكن أباتشي كومونز-io لديه

لاحظ أن هذه هي المكتبات المشار إليها في إجابة بيتر لموقع koders.com، فقط روابط للمكتبة بدلاً من كود المصدر.

هل تحاول كتابة محتويات ملف Reader إلى OutputStream؟إذا كان الأمر كذلك، سيكون من الأسهل عليك تغليف المنتج OutputStream في OutputStreamWriter واكتب charق من Reader إلى Writer, ، بدلاً من محاولة تحويل القارئ إلى ملف InputStream:

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block

تحذير عند استخدام WriterOutputStream - فهو لا يتعامل دائمًا مع كتابة البيانات الثنائية إلى ملف بشكل صحيح/مثل دفق الإخراج العادي.لقد واجهت مشكلة مع هذا الأمر واستغرقت بعض الوقت لتعقبها.

إذا كان بإمكانك، فإنني أوصي باستخدام دفق الإخراج كقاعدة لك، وإذا كنت بحاجة إلى كتابة سلاسل، فاستخدم غلاف OUTputStreamWriter حول الدفق للقيام بذلك.يعد تحويل النص إلى بايت أكثر موثوقية بكثير من العكس، وهو على الأرجح سبب عدم كون WriterOutputStream جزءًا من مكتبة Java القياسية

يمكنك استخدام الصبار (لا توجد طرق ثابتة، كائنات فقط):

يمكنك التحويل بالعكس أيضًا:

لقراءة سلسلة في الدفق باستخدام ما توفره جافا فقط.

InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top