JavaRush /مدونة جافا /Random-AR /الإدخال/الإخراج في جافا. فئات FileInputStream، FileOutput...

الإدخال/الإخراج في جافا. فئات FileInputStream، FileOutputStream، BufferedInputStream

نشرت في المجموعة
مرحبًا! في محاضرة اليوم سنواصل الحديث حول تدفقات الإدخال والإخراج في Java، أو Java I/O (“الإدخال والإخراج”) للاختصار. هذه ليست المحاضرة الأولى حول هذا الموضوع، ولن تكون الأخيرة :) لقد حدث أن Java كلغة توفر العديد من الفرص للعمل مع الإدخال/الإخراج. هناك عدد لا بأس به من الفئات التي تنفذ هذه الوظيفة، لذلك قمنا بتقسيمها إلى عدة محاضرات حتى لا تحتار في البداية :) الإدخال/الإخراج في جافا.  فئات FileInputStream، FileOutputStream، BufferedInputStream - 1في المحاضرات السابقة تطرقنا إلى BufferedReader بالإضافة إلى الفئات المجردة InputStream وOutputStream والعديد من الفئات أحفاد. اليوم سنلقي نظرة على 3 فئات جديدة: FileInputStream و FileOutputStream و BufferedInputStream .

فئة FileOutputStream

الغرض الرئيسي من فئة FileOutputStream هو كتابة البايتات إلى ملف. لا شيء معقد :) FileOutputStream هو أحد تطبيقات فئة OutputStream المجردة . في المنشئ، تأخذ كائنات هذه الفئة إما المسار إلى الملف الهدف (الذي يجب كتابة البايتات إليه) أو كائن من الفئة File. دعونا ننظر إلى كلا المثالين:
public class Main {

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


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
عند إنشاء كائن، Fileحددنا في المنشئ المسار الذي يجب أن يكون موجودًا فيه. ليست هناك حاجة لإنشائه مسبقًا: إذا لم يكن موجودًا، فسيقوم البرنامج بإنشائه بنفسه. يمكنك الاستغناء عن إنشاء كائن إضافي وتمرير سلسلة بالعنوان:
public class Main {

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


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
والنتيجة في كلتا الحالتين ستكون هي نفسها. يمكننا فتح ملفنا ونرى هناك:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
ومع ذلك، هناك تحذير واحد هنا. حاول تشغيل الكود من المثال أعلاه عدة مرات متتالية، ثم انظر إلى الملف وأجب عن السؤال: كم عدد الأسطر التي تراها مكتوبة فيه؟ واحد فقط. لكنك قمت بتشغيل الكود عدة مرات. ومع ذلك، اتضح أنه تم الكتابة فوق البيانات في كل مرة، لتحل محل البيانات القديمة. ماذا لو لم نكن راضين عن هذا ونحتاج إلى تسجيل متسلسل؟ ماذا لو أردنا أن نكتب تحيتنا إلى ملف ثلاث مرات متتالية؟ كل شيء بسيط هنا. نظرًا لأن اللغة نفسها لا يمكنها معرفة نوع السلوك الذي نحتاجه في كل حالة، FileOutputStreamفيمكنك تمرير معلمة إضافية إلى المُنشئ - boolean append. إذا كانت قيمته صحيحة ، سيتم كتابة البيانات إلى نهاية الملف. إذا كانت القيمة false (والقيمة الافتراضية خاطئة )، فسيتم مسح البيانات القديمة وكتابة بيانات جديدة. لنختبر ونقوم بتشغيل الكود المعدل ثلاث مرات:
public class Main {

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


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
النتيجة في الملف:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
شيء آخر! ضع هذه الميزة في الاعتبار عند استخدام فئات الإدخال/الإخراج. في وقت من الأوقات، اضطررت إلى الجلوس لساعات في المهام لفهم أين ذهبت بياناتي القديمة من الملفات :) وبالطبع، كما هو الحال في فئات الإدخال/الإخراج الأخرى، لا تنس تحرير الموارد من خلال ملف close().

فئة FileInputStream

للفئة FileInputStreamغرض معاكس - قراءة البايتات من الملف. تمامًا مثل FileOutputStreamالوراثة OutputStream، هذه الفئة مشتقة من الفئة المجردة InputStream. لنكتب عدة أسطر من النص في النص " test.txt ":

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
الإدخال/الإخراج في جافا.  فئات FileInputStream، FileOutputStream، BufferedInputStream - 2 هذا هو ما يتم تنفيذه لقراءة البيانات من ملف باستخدام FileInputStream:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
نقرأ بايتًا واحدًا من الملف، ونحول بايتات القراءة إلى أحرف ونخرجها إلى وحدة التحكم. وهذه هي النتيجة في وحدة التحكم:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

فئة BufferedInputStream

أعتقد، في ضوء المعرفة من المحاضرات السابقة، يمكنك بسهولة معرفة سبب الحاجة إلى الفصل BufferedInputStreamوما هي المزايا التي يتمتع بها FileInputStream:) لقد التقينا بالفعل بالتدفقات المخزنة، لذا حاول التخمين (أو التذكر) قبل مواصلة القراءة :) التدفقات المخزنة هناك حاجة في المقام الأول لتحسين الإدخال/الإخراج. يعد الوصول إلى مصدر بيانات، مثل القراءة من ملف، عملية كثيفة الأداء. والوصول إلى الملف لقراءة بايت واحد في كل مرة يعد إهدارًا. لذلك، BufferedInputStreamفإنه يقرأ البيانات ليس بايتًا واحدًا في المرة الواحدة، ولكن في كتل ويخزنها مؤقتًا في مخزن مؤقت خاص. يتيح لنا ذلك تحسين تشغيل البرنامج عن طريق تقليل عدد مرات الوصول إلى الملف. دعونا نرى كيف يبدو:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
هنا قمنا بإنشاء كائن BufferedInputStream. فهو يقبل كائنًا أو أيًا من الكائنات اللاحقة له كمدخل InputStream، وبالتالي فإن الكائن السابق FileInputStreamسيفعل ذلك. يأخذ حجم المخزن المؤقت بالبايت كمعلمة إضافية. الآن، بفضل هذا، سيتم قراءة البيانات من الملف ليس بايت واحد في المرة الواحدة، ولكن 200 بايت في المرة الواحدة! تخيل كم قمنا بتقليل عدد مرات الوصول إلى الملفات. لمقارنة الأداء، يمكنك أخذ ملف نصي كبير يبلغ حجمه عدة ميغابايت ومقارنة الوقت المستغرق لقراءته وإخراجه إلى وحدة التحكم بالمللي ثانية باستخدام FileInputStreamو BufferedInputStream. فيما يلي كلا المثالين للكود:
public class Main {

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

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

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

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
عند قراءة ملف بحجم 1.5 ميغابايت على جهاز الكمبيوتر الخاص بي، FileInputStreamقام بالمهمة في حوالي 3500 مللي ثانية، لكنه BufferedInputStreamأنجز المهمة هنا في حوالي 1700 مللي ثانية. كما ترون، أدى التدفق المخزن إلى تحسين أداء البرنامج مرتين! :) سنواصل دراسة فصول I/O - نراكم قريبًا!
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION