سؤال

لماذا يتعطل الأسلوب التالي؟

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
    }
}
هل كانت مفيدة؟

المحلول

الإجابة على سؤالي الخاص:عليك الاتصال buf.clear() بين readس.محتمل، read معلق لأن المخزن المؤقت ممتلئ.الكود الصحيح هو

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
      buf.clear();
    }
}

نصائح أخرى

وأود أن أفترض أنه هو طريق مسدود.يقوم in.read(buf) بتأمين CharBuffer ويمنع استدعاء out.append(buf).

هذا على افتراض أن CharBuffer يستخدم الأقفال (من نوع ما) في التنفيذ.ماذا تقول واجهة برمجة التطبيقات (API) عن فئة CharBuffer؟

يحرر:آسف، هناك نوع من الدائرة الكهربائية القصيرة في عقلي...لقد خلطت بينه وبين شيء آخر.

لا تعمل CharBuffers مع القراء والكتاب بشكل نظيف كما تتوقع.على وجه الخصوص، لا يوجد Writer.append(CharBuffer buf) طريقة.الطريقة التي يطلق عليها مقتطف السؤال هي Writer.append(CharSequence seq), ، الذي يدعو فقط seq.toString().ال CharBuffer.toString() تقوم الطريقة بإرجاع قيمة سلسلة المخزن المؤقت، ولكنها لا تستنزف المخزن المؤقت.النداء اللاحق ل Reader.read(CharBuffer buf) يحصل على مخزن مؤقت ممتلئ بالفعل، وبالتالي يُرجع 0، مما يجبر الحلقة على الاستمرار إلى أجل غير مسمى.

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

على الرغم من كونه مزعجًا، فإنني أوصي بتنفيذ char[] فقط لأن حل CharBuffer يؤدي إلى بناء ما لا يقل عن اثنين من char[] جديدين في كل مرور عبر الحلقة.

public void pipe(Reader in, Writer out) throws IOException {
    char[] buf = new char[DEFAULT_BUFFER_SIZE];
    int count = in.read(buf);
    while( count >= 0 ) {
        out.write(buf, 0, count);
        count = in.read(buf);
    }
}

أوصي باستخدام هذا فقط إذا كنت بحاجة إلى دعم التحويل بين ترميزين للأحرف، وإلا فسيكون تنفيذ ByteBuffer/Channel أو byte[]/IOStream هو الأفضل حتى إذا كنت تقوم بتوصيل الأحرف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top