ينشأ مفهوم "الدفق" من مفهوم الأنبوب في UNIX. في UNIX، الأنبوب عبارة عن تدفق بايت غير متقطع يستخدم لتنفيذ الاتصال بين البرامج أو العمليات، أو لقراءة وكتابة الأجهزة الطرفية، والملفات الخارجية، وما إلى ذلك. وهو يحمي تفاصيل معالجة البيانات في جهاز الإدخال/الإخراج الفعلي. يجب أن يكون للتدفق مصدر ووجهة، والتي يمكن أن تكون مناطق معينة من ذاكرة الكمبيوتر، أو ملفات القرص، أو حتى عنوان URL على الإنترنت. اتجاه التدفق مهم وفقا لاتجاه التدفق، يمكن تقسيم التدفق إلى فئتين: تدفق المدخلات وتدفق الإخراج. في الواقع، الإدخال/الإخراج مخصص للذاكرة. في الواقع، يمكن اعتبار مصدر الدفق ووجهته ببساطة منتجين ومستهلكين للبايتات. بالنسبة لتدفق الإدخال، لا تحتاج إلى الاهتمام بمصدره، طالما أنك تقرأ البيانات من الدفق ببساطة بالنسبة لتدفق الإدخال، يمكن أيضًا أن يكون دفق الإخراج غير مدرك لوجهته ويقوم ببساطة بكتابة البيانات إلى الدفق.
أ. الدفق: مجموعة من تسلسلات البيانات المرتبة.
ب دفق البايت: أصغر وحدة بيانات في دفق البيانات هي البايتات.
ج. دفق الأحرف: أصغر وحدة بيانات في دفق البيانات هي حرف.
1. تتوافق الفئات الموجودة في حزمة java.io مع نوعين من التدفقات
أحد أنواع الدفق يقرأ أو يكتب مباشرة من موقع محدد (مثل ملف قرص أو منطقة ذاكرة). ويسمى هذا النوع من الدفق دفق العقدة، ويسمى الدفق الآخر دفق التصفية (تدفقات التعبئة والتغليف).
تصفية التدفقات: يمكن لبعض التدفقات تلقي البايتات من الملفات وأماكن أخرى، ويمكن للتدفقات الأخرى دمج البايتات في أنواع بيانات أكثر فائدة. المُنشئ الذي يمرر دفقًا موجودًا إلى دفق آخر ويجمع بين الدفقين يسمى الدفق المدمج بالدفق المُصفى. غالبًا ما يستخدم دفق إدخال المرشح تدفقات إدخال أخرى كمصدر إدخال، بعد التصفية أو المعالجة، يتم توفيره للمستخدم في شكل دفق إدخال جديد. نادرًا ما نستخدم فئة واحدة لإنشاء كائن تدفق، ولكن بدلاً من ذلك نقدم الوظيفة المطلوبة عن طريق تراكب كائنات متعددة (أي نمط تصميم الديكور).
في الواقع، يتم توريث تدفقات الإدخال والإخراج شائعة الاستخدام في Java من أربع فئات مجردة، وهي:
استنادًا إلى فئة InputStream أحادية البايت، فئة OutputStream (الإدخال/الإخراج الموجهة بالبايت)
فئات القارئ والكاتب بناءً على وحدات كود Unicode مزدوجة البايت (الإدخال/الإخراج الموجه نحو الأحرف)
بمجرد فتح دفق الإدخال، يمكن للبرنامج قراءة البيانات بشكل تسلسلي من دفق الإدخال. تكون عملية قراءة/كتابة البيانات من دفق الإدخال بشكل عام كما يلي: فتح قناة دفق --> قراءة/كتابة المعلومات --> إغلاق قناة الدفق.
في منصة Java، هناك طريقتان للحصول على نوع ترميز الأحرف الخاص بالمنصة المحلية:
(أ) System.getProperty("file.encoding");
(ب) Charset cs=Charset.defaultCharset();
يمكن تقسيم جميع تدفقات الإدخال وتدفقات الإخراج إلى تدفقات بايت (إدخال وإخراج) وتدفقات أحرف (إدخال وإخراج) هي في الأساس سلسلة (OutputStream/InputStream)، وتلك التي تعالج الأحرف هي بشكل أساسي (Reader/Write). ) مسلسل
2. تدفقات الإدخال الموجهة بالبايت (سلسلة InputStream)، يمكن توصيل هذه الفئات بكائنات FileInputStream لتوفير واجهات مفيدة:
ByteArrayInputStream: استخدم مخزنًا مؤقتًا في الذاكرة باعتباره InputStream
StringBufferInputStream (تم إهماله في java1.1): استخدم كائن سلسلة باعتباره InputStream، ويستخدم التنفيذ الأساسي StringBuffer
FileInputStream: استخدم ملفًا باعتباره InputStream لتنفيذ عملية قراءة الملف (اسم الملف، الملف، كائن FileDescriptor)
PipedInputStream: يطبق مفهوم الأنبوب، ويستخدم بشكل أساسي في الخيوط (كمصدر بيانات في عمليات متعددة)
SequenceInputStream: دمج InputStreams المتعددة في InputStream واحد
يمكن توصيل تدفقات الإخراج الموجهة بالبايت (سلسلة OutputStream) بكائنات FilterOutputStream لتوفير واجهات مفيدة:
ByteArrayOutputStream: إنشاء مخزن مؤقت في الذاكرة، وتخزين المعلومات في مخزن مؤقت في الذاكرة، وتهيئة حجم المخزن المؤقت (اختياري)
FileOutputStream: تخزين المعلومات في ملف (اسم الملف، الملف، FileDescriptor)
PipedOutputStream: يطبق مفهوم الأنبوب، والذي يستخدم بشكل أساسي في سلاسل العمليات (يحدد وجهة البيانات لخيوط متعددة)
3. السلسلة المقابلة (القارئ/الكاتب) :
القارئ: يتوافق مع InputStream، محول InputStreamReader
الكاتب: يتوافق مع OutputStream، والمحول هو OutputStreamWriter
قارئ الملفات: يتوافق مع FileOutputStream
FileWriter: يتوافق مع FileOURputStream
StringReader: لا توجد فئة مقابلة
StringWriter: يتوافق مع ByteArrayInputStream
CharArrayReader: يتوافق مع ByteArrayOutputStream
CharArrayWriter: يتوافق مع ByteArrayOutputStream
PipedReader: يتوافق مع PipedInputStream
PipedWriter: يتوافق مع PipedOutputStream
4. التحويل بين تيارين غير مقيدين ( باستخدام فئة المحول)
InputStreamReader وOutputStreamReader: تحويل دفق موجه للبايت إلى دفق موجه للأحرف.
InputStreamReader عبارة عن جسر من دفق بايت إلى دفق أحرف: فهو يقرأ البايتات باستخدام مجموعة أحرف محددة ويفك تشفيرها إلى أحرف. يمكن تحديد مجموعة الأحرف التي تستخدمها بالاسم أو تقديمها بشكل صريح، أو يمكنها قبول مجموعة الأحرف الافتراضية للنظام الأساسي.
OutputStreamWriter عبارة عن جسر من دفق الأحرف إلى دفق البايت: يمكن ترميز الأحرف المراد كتابتها إلى الدفق إلى بايت باستخدام مجموعة الأحرف المحددة. يمكن تحديد مجموعة الأحرف التي يستخدمها بالاسم أو تقديمها بشكل صريح، وإلا سيتم قبول مجموعة الأحرف الافتراضية للنظام الأساسي
5. قراءة البيانات من InputStream من خلال FilterInputStream :
DataInputStream: قراءة بيانات النوع الأساسي (int، char، long، إلخ) من الدفق.
BufferedInputStream: استخدم المخزن المؤقت لمنع الاضطرار إلى إجراء عملية قراءة فعلية في كل مرة
LineNumberInputStream: سيتم تسجيل عدد الأسطر في دفق الإدخال، ثم استدعاء getLineNumber() وsetLineNumber(int)
PushbackInputStream: نادرًا ما يستخدم، ويستخدم بشكل عام لتطوير المترجم
الكتابة إلى OutputStream من خلال FilterOutputStream:
DataIOutputStream: يمكن إخراج بيانات النوع الأساسي (int، char، long، إلخ) إلى الدفق وفقًا لطريقة الزرع.
BufferedOutputStream: استخدم المخزن المؤقت لتجنب الكتابة الفعلية في كل مرة ترسل فيها البيانات
PrintStream: ينتج مخرجات منسقة، حيث يعالج DataOutputStream تخزين البيانات ويعالج PrintStream العرض
6. تغيير سلوك الدفق
على الرغم من أن BufferedOutputStream هي فئة فرعية من FilterOutputStream، فإن BufferedWriter ليس فئة فرعية من FilterWriter (FilterWriter هي فئة مجردة ولا تحتوي على أي فئات فرعية)
لا توجد فئة مقابلة لـ DataInputStream. استخدم DataInputStream إلا إذا كنت تستخدم BufferedReader بدلاً من ذلك عندما تريد استخدام readLine()
BufferedReader: يتوافق مع BufferedInputStream
LineNumberReader: يتوافق مع LineNumberInputStream
PushBackReader: يتوافق مع PushbackInputStream
BufferedWrite: يتوافق مع BufferedOutStream
PrintWrite: يتوافق مع PrintStream
7. فئة مستقلة ذاتيًا: RandomAccessFile
هذه الفئة مناسبة للملفات المكونة من سجلات ذات حجم معروف. بالإضافة إلى تنفيذ واجهات DataInput وDataOutput (DataInputStream وDataOutputStream ينفذان أيضًا هاتين الواجهتين)، فإن RandomAccessFile هي فئة مستقلة تمامًا ولها أنواع أخرى من الإدخال / الإخراج سلوكيات مختلفة، يمكن أن تتحرك للأمام والخلف داخل الملف، ويتم اشتقاقها مباشرة من الكائن.
يمكن إكمال عمليات القراءة والكتابة على الملفات من خلال كائن RandomAccessFile.
عند إنشاء كائن، يمكنك تحديد طبيعة الملف الذي سيتم فتحه: r، للقراءة فقط؛ w، للكتابة فقط؛
يمكنك الانتقال مباشرة إلى الموقع المحدد في الملف
تم استبدال معظم وظائف RandomAccessFile (وليس كلها) بملفات تعيين تخزين nio