هل هناك سبب لاستخدام BufferedReader بدلاً من InputStreamReader عند قراءة جميع الأحرف؟

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

سؤال

أستخدم حاليًا الوظيفة التالية لإجراء عملية HTTP GET بسيطة.

public static String download(String url) throws java.io.IOException {
    java.io.InputStream s = null;
    java.io.InputStreamReader r = null;
    //java.io.BufferedReader b = null;
    StringBuilder content = new StringBuilder();
    try {
        s = (java.io.InputStream)new URL(url).getContent();

        r = new java.io.InputStreamReader(s);
        //b = new java.io.BufferedReader(r);

        char[] buffer = new char[4*1024];
        int n = 0;
        while (n >= 0) {
            n = r.read(buffer, 0, buffer.length);
            if (n > 0) {
                content.append(buffer, 0, n);
            }
        }
    }
    finally {
        //if (b != null) b.close();
        if (r != null) r.close();
        if (s != null) s.close();
    }
    return content.toString();
}

لا أرى أي سبب لاستخدام BufferedReader لأنني سأقوم بتنزيل كل شيء بالتسلسل.هل أنا على حق في التفكير أنه لا فائدة من ذلك BufferedReader في هذه الحالة؟

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

المحلول

في هذه الحالة، سأفعل ما تفعله (استخدم مصفوفة بايت للتخزين المؤقت وليس أحد المخازن المؤقتة للتيار).

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

لا علاقة له بذلك، ولكن أعتقد أنه يجب عليك إعادة كتابة التعامل مع البث الخاص بك.يعمل هذا النمط بشكل أفضل لتجنب تسرب الموارد:

    InputStream stream = new FileInputStream("in");
    try { //no operations between open stream and try block
        //work
    } finally { //do nothing but close this one stream in the finally
        stream.close();
    }

إذا كنت تفتح تدفقات متعددة، فقم بحظر المحاولة/أخيرًا.

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

نصائح أخرى

أنت على صواب، إذا كنت تستخدم BufferedReader لقراءة محتوى HTTP ورؤوسه، فستحتاج إلى InputStreamReader حتى تتمكن من قراءة البايت مقابل البايت.

يقوم BufferedReader في هذا السيناريو أحيانًا بأشياء غريبة... خاصة عندما يتعلق الأمر بقراءة رؤوس HTTP POST، في بعض الأحيان لن تتمكن من قراءة بيانات POST، إذا كنت تستخدم InputStreamReader، فيمكنك قراءة طول المحتوى وقراءة العديد من وحدات البايت. .

كل استدعاء لواحد من قارئ الإدخالقد تتسبب أساليب read() الخاصة بـ في قراءة بايت واحد أو أكثر من دفق إدخال البايت الأساسي.لتمكين التحويل الفعال للبايتات إلى أحرف، قد تتم قراءة عدد أكبر من البايتات من الدفق الأساسي أكثر مما هو ضروري لتلبية عملية القراءة الحالية.

يخبرني حدسي أنه نظرًا لأنك تقوم بالفعل بإجراء التخزين المؤقت باستخدام مصفوفة البايت، فمن الزائد عن الحاجة استخدام BufferedReader.

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