Java BufferedReader: كيفية قراءة ملف مع مثال

⚡ ملخص ذكي

Java Bufferيقرأ برنامج edReader النص من دفق الإدخال عن طريق تخزين الأحرف مؤقتًا، مما يجعل قراءة الملفات سطرًا بسطر سريعة وبسيطة.ping قارئ ملفات بالداخل BufferedReader و looping عند قراءة السطر حتى يتم إرجاع قيمة فارغة، يتم طباعة الملف بأكمله.

  • ؟؟؟؟ الغرض الأساسي: Bufferيقوم edReader بتغليف أي قارئ تكون عمليات القراءة الخاصة به مكلفة، مما يقلل من عمليات القراءة الفردية مقابل التدفق الأساسي.
  • 🔁 حلقة القراءة: تقوم الدالة readLine بإرجاع سطر واحد لكل استدعاء وقيمة فارغة في نهاية الملف، لذا فإن حلقة while على تلك النتيجة تتصفح الملف بأكمله.
  • 🧱 المسارات البديلة: A Windows مسار داخل Java يحتاج النص إلى شرطة مائلة عكسية مزدوجة، وإلا سيرفض المترجم تسلسل الهروب غير الصالح.
  • ♻️ إصدار الموارد: يؤدي إغلاق القارئ إلى تحرير مقبض الملف الأساسي؛ ويقوم try-with-resources بتنفيذ هذا الإغلاق تلقائيًا.
  • ⌨️ إدخال وحدة التحكم: التفافping يسمح System.in في InputStreamReader لنفس الفئة بقراءة مدخلات لوحة المفاتيح بدلاً من ملف.
  • 🇧🇷 تباين الماسح الضوئي: Bufferيُعد edReader أسرع ويعيد الأسطر الخام، بينما يقوم Scanner بتحليل الرموز والأنواع الأولية مباشرة.
  • 🔤 تحذير بشأن الأحرف: يطبق برنامج FileReader مجموعة الأحرف الافتراضية، لذا فإن تحديد مجموعة أحرف بشكل صريح يتجنب ظهور الأحرف المشوهة عبر الأجهزة.

Bufferالقارئ في Java

كيفية قراءة ملف في Java?

Java توفر عدة آليات لقراءة الملفات. الحزمة الأكثر فائدة لهذا الغرض هي java.io، الذي عضلات بطنهtract Reader يُعرّف هذا الصنف قراءة تدفق الأحرف. java.io.BufferedReader هي الفئة الفرعية الملموسة المستخدمة للقراءة الفعالة القائمة على الأسطر.

ما هي تفاصيل Bufferالقارئ في Java?

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

ولذلك فمن المستحسن التفاف Bufferقارئ edReader حول أي قارئ read() قد تكون العمليات مكلفة، مثل FileReader و InputStreamReader. في الاستخدام النموذجي، يتم تمرير مسار الملف إلى القارئ على النحو التالي:

// Note the doubled backslash: a single \ starts an escape sequence
objReader = new BufferedReader(new FileReader("D:\\DukesDiary.txt"));

يؤدي هذا إلى تحميل الملف في objReaderثم تقوم بالمرور على محتويات الملف وطباعة كل سطر. تقرأ حلقة while في الكود أدناه الملف حتى تصل إلى نهايته.

while ((strCurrentLine = objReader.readLine()) != null) {
    System.out.println(strCurrentLine);
}

strCurrentLine يمسك بالخط الحالي، و objReader.readLine() تُرجع الدالة سلسلة نصية. ولذلك، تستمر الحلقة في التكرار طالما أن القيمة المُعادة ليست فارغة، وتتوقف عند أول قيمة فارغة، مما يشير إلى نهاية الملف.

Bufferمثال على القارئ الإلكتروني

الكود أدناه هو كود كامل Java Bufferمثال على برنامج edReader:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample {

    public static void main(String[] args) {
        BufferedReader objReader = null;
        try {
            String strCurrentLine;

            objReader = new BufferedReader(new FileReader("D:\\DukesDiary.txt"));

            while ((strCurrentLine = objReader.readLine()) != null) {
                System.out.println(strCurrentLine);
            }

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (objReader != null)
                    objReader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

ملاحظة: استخدم finally يُعدّ تقسيم البيانات أمرًا بالغ الأهمية. فهو يضمن ذلك. objReader.close() يتم تشغيل هذا الإجراء سواء تم طرح استثناء أم لا، مما يؤدي إلى تحرير مؤشر الملف الأساسي والاحتفاظ به. إدارة الذاكرة متوقع. محاولة متداخلة في الداخل finally مطلوب لأن close() وتعلن بنفسها IOException.

Bufferمثال على edReader JDK7

ابتداءً من JDK 7، تقوم try-with-resources بإزالة finally حظر كامل. أي مورد مُعلن بين قوسين من try يتم إغلاق العبارة تلقائيًا عند خروج الكتلة، بترتيب عكسي للإنشاء، حتى في حالة انتشار استثناء:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFileExample_jdk7 {

    private static final String FILENAME = "D:\\DukesDiary.txt";

    public static void main(String[] args) {

        try (BufferedReader br = new BufferedReader(new FileReader(FILENAME))) {

            String strCurrentLine;

            while ((strCurrentLine = br.readLine()) != null) {
                System.out.println(strCurrentLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

هذه النسخة أقصر وأكثر أمانًا، لذا يُفضّل استخدامها في كتابة التعليمات البرمجية الجديدة. قراءة الملف ليست سوى استخدام واحد لهذه الفئة؛ يقارن القسم التالي هذه النسخة بالبديل الذي يلجأ إليه معظم المبتدئين أولًا.

Bufferقارئ الكتب الإلكترونية مقابل الماسح الضوئي: أيهما تستخدم؟

كلا النوعين من البرامج يقرأ النصوص، وغالبًا ما يختار المبتدئون أحدهما عشوائيًا. يحل كل منهما مشاكل مختلفة، ويظهر الاختيار الخاطئ إما في صورة تحليل يدوي غير دقيق أو في انخفاض الإنتاجية عندما يصل حجم المدخلات إلى آلاف الأسطر. الجدول أدناه يقارن بينهما جنبًا إلى جنب.

البعد BufferedReader الماسح الضوئي
سياسات الإرجاع والاستبدال الأسطر الكاملة كسلسلة الرموز والبيانات الأولية التي تم تحليلها
تحليل مدمج لا — أنت تنقسم أو تعتنق بنفسك نعم — nextInt، التاليDouble، الخط التالي
المخزن المؤقت الافتراضي الأحرف 8192 الأحرف 1024
سرعة التعامل مع الملفات الكبيرة أسرع أبطأ، بسبب تجزئة الرموز باستخدام التعبيرات النمطية
أمان الخيوط Syncمُكرّس غير متزامن
أفضل ل قراءة الملفات الكبيرة سطرًا بسطر مدخلات تفاعلية صغيرة تتطلب إدخال قيم مكتوبة

اختار Bufferيُستخدم edReader عندما يكون الهدف هو التنقل بسرعة عبر ملف والتعامل مع النص بنفسك، بينما يُستخدم Scanner عندما تريد قيمًا مكتوبة دون كتابة كود تحويل. يتم تقسيم كل سطر مُعاد باستخدام طريقة تقسيم السلسلة يعطي Bufferيوفر برنامج edReader معظم مزايا الماسح الضوئي بسرعة أعلى.

كيفية قراءة مدخلات وحدة التحكم باستخدام BufferedReader

تقرأ نفس الفئة مدخلات لوحة المفاتيح، وهو أمر مفيد لبرامج سطر الأوامر الصغيرة ولمدخلات تحديات البرمجة. System.in هو عبارة عن سلسلة بايتات، لذا لا يمكن تمريره إلى BufferedReader مباشرة. InputStreamReader يربط البايتات بالأحرف، و Bufferثم يضيف برنامج edReader ميزة قراءة الأسطر بكفاءة فوق تلك الميزة الأساسية.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadConsoleExample {

    public static void main(String[] args) throws IOException {

        // Bridge the System.in byte stream to a character stream
        try (BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in))) {

            System.out.print("Enter your name: ");
            String name = reader.readLine();

            System.out.print("Enter your age: ");
            // readLine always returns text, so convert it explicitly
            int age = Integer.parseInt(reader.readLine().trim());

            System.out.println("Hello " + name + ", age " + age);
        }
    }
}

ثلاثة تفاصيل جديرة بالتذكر. أولاً، readLine() تُرجع دائمًا سلسلة نصية، لذا يجب تحويل المدخلات الرقمية باستخدام Integer.parseInt أو ما شابه، وإذا تم إدخال قيمة غير رقمية، فسيتم طرح خطأ. NumberFormatException — قم بتغليف عملية التحويل إذا كان المدخل غير موثوق به. ثانيًا، استدعاء .trim() يزيل سطر الإرجاع الأخير الذي Windows تُلحق البيانات في وحدة التحكم، وهو سبب شائع لفشل التحليل. ثالثًا، تجنب إغلاق قارئ مُحاط بـ System.in إذا كان البرنامج لا يزال بحاجة إلى إدخال وحدة التحكم لاحقًا، لأن إغلاق الغلاف يغلق التدفق الأساسي بشكل دائم لتلك العملية.

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

حتى مع وجود الكود الصحيح، تظهر بعض الأخطاء بشكل متكرر.

مشترك Bufferأخطاء برنامج edReader وكيفية إصلاحها

معظم Bufferتنشأ أخطاء برنامج edReader من مسارات الملفات، أو معالجة الموارد، أو ترميز الأحرف، وليس من حلقة القراءة نفسها. يوضح كل خطأ أدناه الاستثناء الخاص به وحلّه.

  • شخصية هروب غير قانونية: يستخدم المسار شرطة مائلة عكسية واحدة، كما في "D:\DukesDiary.txt". Double إلى "D:\\DukesDiary.txt"أو استخدم الشرطة المائلة، والتي Java يقبل Windows.
  • استثناء FileNotFoundException: المسار نسبي إلى دليل العمل، وليس إلى ملف المصدر. اطبع new File(name).getAbsolutePath() لنرى أين Java إنه ينظر بالفعل.
  • حدث خطأ NullPointerException عند القراءة الأولى: لم يتم تعيين القارئ مطلقًا لأن المُنشئ أطلق استثناءً، وتم تجاهله. تحقق من معالجة الاستثناء قبل الحلقة.
  • أحرف مشوهة أو علامات استفهام: الملف بتنسيق UTF-8 ولكن FileReader تم تطبيق ترميز الأحرف الافتراضي للنظام الأساسي. قم بتمرير ترميز الأحرف بشكل صريح، على سبيل المثال new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8).
  • تم إغلاق البث: تم إغلاق قارئ البيانات داخل الحلقة أو إعادة استخدامه بعد انتهاء عملية البحث عن الموارد. افتح قارئ بيانات جديدًا لكل عملية قراءة للملف.

الأسئلة الشائعة

نعم. يقوم وسيط المُنشئ الثاني بتحديد حجم المخزن المؤقت بالأحرف، على سبيل المثال new BufferedReader(reader, 16384). القيمة الافتراضية 8192 تناسب معظم الملفات؛ رفعها لا يفيد إلا مع عمليات القراءة التسلسلية الكبيرة جدًا.

بالنسبة للملفات الصغيرة، نعم، تُرجع قائمة بالأسطر في استدعاء واحد. أما بالنسبة للملفات الكبيرة، فيُفضّل Files.newBufferedReader or Files.lines، لأن دالة readAllLines تحتفظ بالملف بأكمله في الذاكرة دفعة واحدة.

نعم. AI يقوم المساعدون بإعادة كتابة عملية تنظيف كتلة finally إلى try-with-resources ويقترحون بدائل NIO. تحقق من مجموعة الأحرف وسلوك الاستثناء بعد ذلك، لأن التحويلات المُولَّدة غالبًا ما تحذف الترميز الصريح.

يقوم الذكاء الاصطناعي بقراءة المكدس tracيحدد هذا البرنامج ما إذا كان السبب هو دليل عمل خاطئ، أو أذونات مفقودة، أو عدم تطابق في الترميز. يُسهّل هذا البرنامج عملية التشخيص، مع أن الحل لا يزال بحاجة إلى التحقق منه على الملف الأصلي.

لا، تقوم دالة readLine بإزالة فاصل الأسطر، لذا فإن السلسلة النصية المُعادة لا تحتوي على سطر جديد في نهايتها. وبالتالي، فإن السطر الفارغ في الملف يُعيد سلسلة نصية فارغة بدلاً من قيمة فارغة (null).

تلخيص هذه التدوينة بـ: