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




(11)

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


Answers

استعمال:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

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

ويستخدم CharSequenceInputStream من مشروع أباتشي كومنز IO.


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

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

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



إذا كنت قد بدأت مع String ، فيمكنك أيضًا القيام بما يلي:

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

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

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



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

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

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

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

ملاحظة: أحد التعليقات على أحد الإجابات الأخرى هنا يذكر issues.apache.org/bugzilla/show_bug.cgi?id=40455 . ولكن هذا يؤثر على فئة Apache Ant ReaderInputStream ( here ) ، وليس فئة Apache Commons IO ReaderInputStream.


لا يمكنك تجنب مشاكل ترميز النص ، ولكن لدى Apache commons-io

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


هل تحاول كتابة محتويات Reader إلى OutputStream ؟ إذا كان الأمر كذلك ، فسوف يكون لديك وقتًا أسهل في التفاف OutputStream في OutputStreamWriter وكتابة char s من 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

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

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

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


تعجبني مكتبة Apache Commons IO. إلقاء نظرة على إصدارها من ByteArrayOutputStream ، الذي له أسلوب toString(String enc) وكذلك toByteArray() . إن استخدام المكونات الموجودة والموثوقة مثل مشروع العموم يتيح لك أن تكون شفرتك أصغر وأسهل في التمديد وإعادة الاستخدام. حظا طيبا وفقك الله.





java stream