تحتوي حزمة Java.io تقريبًا على جميع الفئات اللازمة لتشغيل الإدخال والإخراج. تمثل جميع فئات الدفق هذه مصادر الإدخال ووجهات الإخراج.
تدعم التدفقات الموجودة في حزمة Java.io العديد من التنسيقات، مثل الأنواع الأساسية والكائنات ومجموعات الأحرف المترجمة وما إلى ذلك.
يمكن فهم الدفق على أنه سلسلة من البيانات. يمثل دفق الإدخال قراءة البيانات من المصدر، ويمثل دفق الإخراج كتابة البيانات إلى الوجهة.
توفر Java دعمًا قويًا ومرنًا للإدخال/الإخراج، مما يجعلها مستخدمة على نطاق أوسع في نقل الملفات وبرمجة الشبكات.
لكن هذا القسم يغطي معظم الوظائف الأساسية المتعلقة بالتدفقات والإدخال/الإخراج. وسوف نتعلم هذه الوظائف من خلال الأمثلة واحدة تلو الأخرى.
يتم إدخال وحدة التحكم الخاصة بـ Java بواسطة System.in.
للحصول على دفق أحرف منضم إلى وحدة التحكم، يمكنك التفاف System.in في كائن BufferedReader لإنشاء دفق أحرف.
ما يلي هو بناء الجملة الأساسي لإنشاء BufferedReader:
BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in));
بعد إنشاء كائن BufferedReader، يمكننا استخدام طريقة read() لقراءة حرف من وحدة التحكم، أو طريقة readLine() لقراءة سلسلة.
لقراءة حرف من كائن BufferedReader، استخدم طريقة القراءة () التي يكون تركيبها كما يلي:
intread()throwsIOException
في كل مرة يتم استدعاء الأسلوب read()، فإنه يقرأ حرفًا من تدفق الإدخال ويعيد هذا الحرف كقيمة عددية. يُرجع -1 عند انتهاء الدفق. تطرح هذه الطريقة IOException.
يوضح البرنامج التالي استخدام طريقة القراءة () لقراءة الأحرف بشكل مستمر من وحدة التحكم حتى يقوم المستخدم بإدخال "q".
//使用BufferedReader在控制台读取字符importjava.io.*; publicclassBRRead{ publicstaticvoidmain(Stringargs[])throwsIOException { charc; //使用System.in创建BufferedReader BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in)); System.out.println("输入字符, 按下'q' 键退出."); //读取字符do{ c=(char)br.read(); System.out.println(c); }while(c!='q'); } }
نتائج التجميع والتشغيل للمثال أعلاه هي كما يلي:
输入字符, 按下'q' 键退出. 123abcq 1 2 3 a b c q
تتطلب قراءة سلسلة من الإدخال القياسي استخدام طريقة readLine() في BufferedReader.
وصيغتها العامة هي:
StringreadLine()throwsIOException
يقوم البرنامج التالي بقراءة أسطر الأحرف وعرضها حتى تقوم بإدخال كلمة "نهاية".
//使用BufferedReader在控制台读取字符importjava.io.*; publicclassBRReadLines{ publicstaticvoidmain(Stringargs[])throwsIOException { //使用System.in创建BufferedReader BufferedReaderbr=newBufferedReader(new InputStreamReader(System.in)); Stringstr; System.out.println("Enterlinesoftext."); System.out.println("Enter'end'toquit."); do{ str=br.readLine(); System.out.println(str); }while(!str.equals("end")); } }
نتائج التجميع والتشغيل للمثال أعلاه هي كما يلي:
Enterlinesoftext. Enter'end'toquit. Thisislineone Thisislineone Thisislinetwo Thisislinetwo end end
كما ذكرنا من قبل، يتم إكمال إخراج وحدة التحكم بواسطة print() وprintln(). يتم تعريف هذه الأساليب بواسطة فئة PrintStream، ويعتبر System.out مرجعًا لكائن هذه الفئة.
يرث PrintStream فئة OutputStream وينفذ طريقة الكتابة (). بهذه الطريقة، يمكن أيضًا استخدام write() لكتابة العمليات إلى وحدة التحكم.
يعرّف PrintStream write() في أبسط صوره كما يلي:
voidwrite(intbyteval)
تكتب هذه الطريقة الثمانيات السفلية من البايت إلى الدفق.
يستخدم المثال التالي write() لطباعة الحرف "A" متبوعًا بحرف السطر الجديد على الشاشة:
importjava.io.*; //演示System.out.write(). publicclassWriteDemo{ publicstaticvoidmain(Stringargs[]){ intb; b='A'; System.out.write(b); System.out.write('n'); } }
قم بتشغيل المثال أعلاه لإخراج الحرف "A" في نافذة الإخراج.
A
ملاحظة: لا يتم استخدام طريقة write() كثيرًا لأن طريقتي print() وprintln() أكثر ملاءمة للاستخدام.
كما ذكرنا من قبل، يتم تعريف الدفق على أنه سلسلة من البيانات. يستخدم دفق الإدخال لقراءة البيانات من المصدر، ويستخدم دفق الإخراج لكتابة البيانات إلى الهدف.
الشكل التالي هو رسم تخطيطي للتسلسل الهرمي للفئة يصف دفق الإدخال ودفق الإخراج.
التدفقان المهمان اللذان سيتم مناقشتهما أدناه هما FileInputStream وFileOutputStream:
يُستخدم هذا الدفق لقراءة البيانات من ملف، ويمكن إنشاء كائناته باستخدام الكلمة الأساسية new.
هناك العديد من أساليب البناء المستخدمة لإنشاء الكائنات.
يمكنك استخدام اسم ملف سلسلة لإنشاء كائن دفق إدخال لقراءة الملف:
InputStreamf=newFileInputStream("C:/java/hello");
يمكنك أيضًا استخدام كائن ملف لإنشاء كائن دفق إدخال لقراءة الملف. علينا أولاً إنشاء كائن ملف باستخدام طريقة File():
Filef=newFile("C:/java/hello"); InputStreamf=newFileInputStream(f);
بعد إنشاء كائن InputStream، يمكنك استخدام الطرق التالية لقراءة الدفق أو إجراء عمليات دفق أخرى.
رقم سري | الطرق والوصف |
---|---|
1 | public void Close() throws IOException{} لإغلاق دفق إدخال الملف هذا وتحرير كافة موارد النظام المتعلقة بهذا الدفق. يلقي IOException. |
2 | protected void Finalize()throws IOException {} تقوم هذه الطريقة بمسح الاتصال بالملف. تأكد من استدعاء طريقة الإغلاق لدفق إدخال الملف عندما لا تتم الإشارة إليه. يلقي IOException. |
3 | قراءة int العامة (int r) تطرح IOException {} تقرأ هذه الطريقة وحدات البايت المحددة من البيانات من كائن InputStream. تم إرجاعها كقيمة عددية. إرجاع البايت التالي من البيانات، أو -1 إذا تم الوصول إلى النهاية. |
4 | قراءة int العامة (بايت [] r) تلقي IOException {} تقرأ هذه الطريقة بايتات r.length من دفق الإدخال. إرجاع عدد البايتات المقروءة. إذا كانت هذه هي نهاية الملف، فسيتم إرجاع -1. |
5 | public intavailable() throws IOException{} يُرجع عدد البايتات التي يمكن قراءتها من دفق الإدخال هذا دون حظر بواسطة استدعاء الطريقة التالية على دفق الإدخال هذا. تقوم بإرجاع قيمة عددية. |
بالإضافة إلى InputStream، هناك بعض تدفقات الإدخال الأخرى لمزيد من التفاصيل، يرجى الرجوع إلى الرابط أدناه:
ByteArrayInputStream
DataInputStream
يتم استخدام هذه الفئة لإنشاء ملف وكتابة البيانات إلى الملف.
إذا لم يكن الملف الهدف موجودًا قبل أن يفتح الدفق الملف للإخراج، فسيقوم الدفق بإنشاء الملف.
هناك نوعان من المنشئات التي يمكن استخدامها لإنشاء كائنات FileOutputStream.
قم بإنشاء كائن دفق الإخراج باستخدام اسم ملف السلسلة:
OutputStreamf=newFileOutputStream("C:/java/hello")
يمكنك أيضًا استخدام كائن ملف لإنشاء دفق إخراج للكتابة في الملف. علينا أولاً إنشاء كائن ملف باستخدام طريقة File():
Filef=newFile("C:/java/hello"); OutputStreamf=newFileOutputStream(f);
بعد إنشاء كائن OutputStream، يمكنك استخدام الطرق التالية للكتابة إلى الدفق أو إجراء عمليات دفق أخرى.
رقم سري | الطرق والوصف |
---|---|
1 | public void Close() throws IOException{} لإغلاق دفق إدخال الملف هذا وتحرير كافة موارد النظام المتعلقة بهذا الدفق. يلقي IOException. |
2 | protected void Finalize()throws IOException {} تقوم هذه الطريقة بمسح الاتصال بالملف. تأكد من استدعاء طريقة الإغلاق لدفق إدخال الملف عندما لا تتم الإشارة إليه. يلقي IOException. |
3 | public void write(int w)throws IOException{} تقوم هذه الطريقة بكتابة البايتات المحددة في دفق الإخراج. |
4 | يكتب public void write(byte[] w) بايتات الطول w.length في المصفوفة المحددة إلى OutputStream. |
بالإضافة إلى OutputStream، هناك بعض تدفقات الإخراج الأخرى لمزيد من التفاصيل، يرجى الرجوع إلى الرابط أدناه:
ByteArrayOutputStream
DataOutputStream
فيما يلي مثال يوضح استخدام InputStream وOutputStream:
import java.io.*; public class fileStreamTest { public static void main(String args[]) { try { byte bWrite[] = { 11, 21, 3, 40, 5 }; OutputStream os = new FileOutputStream("test.txt"); for (int x = 0; x < bWrite.length; x++) { os.write(bWrite[x]); // writes the bytes } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for (int i = 0; i < size; i++) { System.out.print((char) is.read() + " "); } is.close(); } catch (IOException e) { System.out.print("Exception"); } } }
يقوم البرنامج أعلاه أولاً بإنشاء الملف test.txt، وكتابة الرقم المحدد في الملف في شكل ثنائي، ثم إخراجه إلى وحدة التحكم.
بما أن التعليمة البرمجية أعلاه مكتوبة بالثنائي، فقد تكون هناك أحرف مشوهة. يمكنك استخدام أمثلة التعليمات البرمجية التالية لحل مشكلة التعليمات البرمجية المشوهة:
//文件名:fileStreamTest2.java importjava.io.*; publicclassfileStreamTest2{ publicstaticvoidmain(String[]args)throwsIOException{ Filef=newFile("a.txt"); FileOutputStreamfop=newFileOutputStream(f); //构建FileOutputStream对象,文件不存在会自动新建OutputStreamWriterwriter=newOutputStreamWriter(fop,"UTF-8"); //构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk writer.append("中文输入"); //写入到缓冲区writer.append("rn"); //换行writer.append("English"); //刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入writer.close(); //关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉fop.close(); //关闭输出流,释放系统资源 FileInputStreamfip=newFileInputStream(f); //构建FileInputStream对象InputStreamReaderreader=newInputStreamReader(fip,"UTF-8"); //构建InputStreamReader对象,编码与写入相同 StringBuffersb=newStringBuffer(); while(reader.ready()){ sb.append((char)reader.read()); //转成char加到StringBuffer对象中 } System.out.println(sb.toString()); reader.close(); //关闭读取流fip.close(); //关闭输入流,释放系统资源 } }
هناك أيضًا بعض الفئات حول الملفات والإدخال/الإخراج التي نحتاج أيضًا إلى معرفتها:
فئة الملف (الفئة)
فئة قارئ الملفات (الفئة)
فئة كاتب الملفات (فئة)
هناك طريقتان في فئة File يمكن استخدامهما لإنشاء المجلدات:
تقوم طريقة mkdir() بإنشاء مجلد وترجع صحيحًا إذا نجحت وخطأ إذا فشلت. يشير الفشل إلى أن المسار المحدد بواسطة كائن الملف موجود بالفعل، أو أنه لا يمكن إنشاء المجلد لأن المسار بأكمله غير موجود بعد.
تقوم طريقة mkdirs() بإنشاء مجلد وجميع المجلدات الأصلية الخاصة به.
يقوم المثال التالي بإنشاء المجلد "/tmp/user/Java/bin":
importjava.io.File; publicclassCreateDir{ publicstaticvoidmain(Stringargs[]){ Stringdirname="/tmp/user/java/bin"; Filed=newFile(dirname); //现在创建目录d.mkdirs(); } }
قم بتجميع وتنفيذ التعليمات البرمجية أعلاه لإنشاء الدليل "/tmp/user/Java/bin".
ملاحظة: تقوم Java تلقائيًا بحل فواصل مسار الملف وفقًا للاتفاقية المتبعة في UNIX وWindows. إذا كنت تستخدم المحدد (/) في إصدار Java لنظام التشغيل Windows، فسيتم تحليل المسار بشكل صحيح.
الدليل هو في الواقع كائن ملف يحتوي على ملفات ومجلدات أخرى.
إذا قمت بإنشاء كائن ملف وهو دليل، فإن استدعاء الأسلوب isDirectory () سيعود صحيحًا.
يمكنك استخراج قائمة الملفات والمجلدات التي يحتوي عليها عن طريق استدعاء الأسلوب list() على الكائن.
يوضح المثال الموضح أدناه كيفية استخدام طريقة list() للتحقق من محتويات المجلد:
importjava.io.File; publicclassDirList{ publicstaticvoidmain(Stringargs[]){ Stringdirname="/tmp"; Filef1=newFile(dirname); if(f1.isDirectory()){ System.out.println("Directoryof"+dirname); Strings[]=f1.list(); for(inti=0;i<s.length;i++){ Filef=newFile(dirname+"/"+s[i]); if(f.isDirectory()){ System.out.println(s[i]+"是一个目录"); }else{ System.out.println(s[i]+"是一个文件"); } } }else{ System.out.println(dirname+"不是一个目录");
} } }
importjava.io.File; publicclassDirList{ publicstaticvoidmain(Stringargs[]){ Stringdirname="/tmp"; Filef1=newFile(dirname); if(f1.isDirectory()){ System.out.println("Directoryof"+dirname); Strings[]=f1.list(); for(inti=0;i<s.length;i++){ Filef=newFile(dirname+"/"+s[i]); if(f.isDirectory()){ System.out.println(s[i]+"是一个目录"); }else{ System.out.println(s[i]+"是一个文件"); } } }else{ System.out.println(dirname+"不是一个目录");
} } }
نتائج التجميع والتشغيل للمثال أعلاه هي كما يلي:
目录/tmp bin 是一个目录lib 是一个目录demo 是一个目录test.txt 是一个文件README 是一个文件index.html 是一个文件include 是一个目录
لحذف ملف، استخدم طريقة java.io.File.delete().
الكود التالي سوف يحذف الدليل /tmp/java/. تجدر الإشارة إلى أنه عند حذف دليل معين، يجب التأكد من عدم وجود ملفات أخرى في الدليل لحذفه بشكل صحيح، وإلا ستفشل عملية الحذف.
هيكل دليل الاختبار:
/تمب/جافا/ |-- 1.سجل |-- اختبار
import java.io.File; public class DeleteFileDemo { public static void main(String args[]) { // 这里修改为自己的测试目录File folder = new File("/tmp/java/"); deleteFolder(folder); } // 删除文件及目录public static void deleteFolder(File folder) { File[] files = folder.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory()) { deleteFolder(f); } else { f.delete(); } } } folder.delete(); } }