pipedoutputstream و pipedInputStream
في Java ، PipedOutputStream و PipedInputStream هي تدفقات إخراج خطوط الأنابيب وتيارات إدخال خط الأنابيب ، على التوالي.
وظيفتها هي السماح لترابطات الترابطات بالتواصل بين الخيوط من خلال خطوط الأنابيب. عند استخدام اتصال خطوط الأنابيب ، يجب استخدام PipedOutputStream و PipedInputStream بالاقتران مع بعضهما البعض.
عند استخدام اتصال خطوط الأنابيب ، فإن العملية العامة هي: نكتب البيانات إلى pipedoutputstream في مؤشر الترابط A ، وسيتم إرسال هذه البيانات تلقائيًا إلى pipedInputStream المقابلة لـ pipedoutputstream ، ثم تخزينها في المخزن المؤقت لـ pipedInputStream ؛ في هذا الوقت ، يقرأ الموضوع B البيانات الموجودة في pipedInputStream. هذا يمكن أن يدرك التواصل بين الموضوع A والموضوع B.
أدناه ، ننظر إلى مثال الاتصال من خلال خطوط الأنابيب في MultiThreads. وتشمل الأمثلة 3 فئات: receiver.java ، pipedstreamtest.java و sender.java.
مدونة المتلقي. جافا كما يلي:
استيراد java.io.ioException ؛ استيراد java.io.pipedInputStream ؛ suppressWarnings ("All") / *** مؤشر ترتيب المتلقي* / جهاز استقبال الفئة العامة يمتد كائن دفق إدخال خط أنابيب. // يرتبط بكائن "pipedOutputStream" ، // هذا يتيح لك استلام بيانات "pipedOutputStream" ثم السماح للمستخدم بقراءته. pipedInputStream الخاص في = جديد pipedInputStream () ؛ // احصل على كائن "دفق إدخال الأنابيب" pipedInputStream getInputStream () {return in ؛ } Override public void run () {readMessageOnce () ؛ // readMessageContinued () ؛ } // اقرأ البيانات مرة واحدة من "دفق إدخال الأنابيب" public void readMessageOnce () {// على الرغم من أن حجم BUF هو 2048 بايت ، إلا أنه سيقرأ فقط على الأقل 1024 بايت من "دفق إدخال الأنابيب". // لأن حجم المخزن المؤقت لـ "دفق إدخال الأنابيب" هو فقط 1024 بايت افتراضيًا. Byte [] buf = new byte [2048] ؛ حاول {int len = in.read (buf) ؛ System.out.println (سلسلة جديدة (buf ، 0 ، len)) ؛ in.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} // عند القراءة> 1024 بايت من "دفق إدخال الأنابيب" ، توقف عن قراءة public void readMessageContinued () {int total = 0 ؛ بينما (صحيح) {byte [] buf = new byte [1024] ؛ حاول {int len = in.read (buf) ؛ المجموع += لين ؛ System.out.println (سلسلة جديدة (buf ، 0 ، len)) ؛ // إذا كان العدد الإجمالي لقراءة البايتات هو> 1024 ، فقم بالخروج من الحلقة. إذا (المجموع> 1024) استراحة ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} حاول {in.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} رمز المرسل. جافا كما يلي:
استيراد java.io.ioException ؛ استيراد java.io.pipedoutputstream ؛ suppressWarnings ("All")/ *** Sender Thread*/ Sender الفئة العامة يمتد مؤشر ترابط {// أنابيب خط إخراج كائن. // يرتبط بكائن "pipedInputStream" ، // هذا يسمح بإرسال البيانات إلى بيانات "PipedInputStream" ، ويمكن للمستخدم بعد ذلك قراءة البيانات من "pipedInputStream". pipedOutputStream الخاص = جديد pipedOutputStream () ؛ // احصل على "دفق إخراج الأنابيب" كائن pipedOutputStream getOutputStream () {return Out ؛ } Override public void run () {writeShortMessage () ؛ // writelongmessage () ؛ } // اكتب رسالة قصيرة إلى "دفق إخراج الأنابيب": "هذه رسالة قصيرة" private void writeShortMessage () {String strinfo = "هذه رسالة قصيرة" ؛ حاول {out.write (strinfo.getbytes ()) ؛ out.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} // اكتب رسالة طويلة إلى "دفق إخراج الأنابيب" private void writeLongMessage () {StringBuilder sb = new StringBuilder () ؛ // اكتب 1020 بايت من خلال حلقة لـ (int i = 0 ؛ i <102 ؛ i ++) sb.append ("0123456789") ؛ // اكتب 26 بايت أكثر. SB.Append ("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ؛ // الطول الإجمالي لـ STR هو 1020+26 = 1046 Bytes String STR = SB.ToString () ؛ جرب {// اكتب 1046 بايت في "دفق إخراج الأنابيب" Out.write (str.getBytes ()) ؛ out.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} رمز pipedstreamtest.java كما يلي:
استيراد java.io.pipedInputStream ؛ استيراد java.io.pipedoutputstream ؛ استيراد java.io.ioException ؛ suppressWarnings ("الكل") / *** البرنامج التفاعلي لدفق إدخال خط الأنابيب ودفق خط الأنابيب* / pipedstreamtest {public static void main (string) {sender sender t1 = جهاز الاستقبال T2 = جهاز استقبال جديد () ؛ pipedOutputStream Out = t1.getOutputStream () ؛ pipedInputStream في = t2.getInputStream () ؛ جرب {// connection. جوهر الجملتين التاليتين هو نفسه. //out.connect(in) ؛ in.connect (out) ؛ /** * ابدأ طريقة فئة مؤشر الترابط: * اجعل مؤشر الترابط يبدأ في التنفيذ ؛ يستدعي جهاز Java Virtual طريقة تشغيل مؤشر الترابط. * النتيجة هي أن خيطين يعملان بشكل متزامن ؛ مؤشر الترابط الحالي (تم إرجاعه من المكالمة إلى طريقة البدء) والموضوع الآخر (تنفيذ طريقة التشغيل الخاصة به). * من غير القانوني بدء موضوع عدة مرات. خاصة عندما ينتهي الخيط من التنفيذ ، لا يمكن إعادة تشغيله. */ t1.start () ؛ t2.start () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} نتائج التشغيل:
هذه رسالة قصيرة
يوضح:
(1) in.connect (out) ؛ يربط "دفق إدخال الأنابيب" و "دفق إخراج الأنابيب". تحقق من رمز المصدر للاتصال () في pipedoutputstream.java و pipedInputStream.java ؛ نحن نعرف Out.connect (in) ؛ يعادل in.connect (out) ؛
(2)
t1.start () ؛ // ابدأ مؤشر ترابط "المرسل" t2.start () ؛ // ابدأ موضوع "المتلقي"
تحقق أولاً من رمز المصدر لـ Sender.java ، وقم بتنفيذ وظيفة Run () بعد بدء تشغيل الخيط ؛ في Run () of sender.java ، اتصل بـ WriteShortMessage () ؛
وظيفة WriteShortMessage () ؛ هو كتابة البيانات "هذه رسالة قصيرة" إلى "دفق إخراج الأنابيب" ؛ سيتم استلام هذه البيانات بواسطة "دفق إدخال الأنابيب". دعونا نرى كيف يتم تحقيق ذلك.
دعونا أولاً نلقي نظرة على الكود المصدر للكتابة (Byte B []) ونحدده في outputstream.java. pipedoutputstream.java وراثي من outputstream.java ؛ رمز المصدر للكتابة (البايت B []) في OutputStream.java كما يلي:
كتابة باطلة عامة (بايت ب []) يلقي ioexception {write (b ، 0 ، b.length) ؛} في الواقع ، اكتب (البايت B []) هي وظيفة كتابة المكالمة (البايت B [] ، int Off ، int len) في pipedoutputstream.java. عند النظر إلى رمز الكتابة المصدر (البايت B [] ، int Off ، int len) ، وجدنا أنه سيتصل بالوعة. receive (B ، Off ، Len) ؛ نعلم أيضًا تعريف استلام (البايت B [] ، int ، int len) ، نحن نعلم أن Sink.Receive (B ، OFF ، LEN) هو حفظ البيانات في "دفق إخراج الأنابيب" في المخزن المؤقت لـ "دفق إدخال الأنابيب". الحجم الافتراضي للمخزن المؤقت لـ "دفق إدخال الأنابيب" هو 1024 بايت.
في هذه المرحلة ، نعلم أن: t1.start () يبدأ مؤشر ترابط المرسل ، وسيقوم مؤشر ترابط المرسل بكتابة البيانات "هذه رسالة قصيرة" إلى "دفق إخراج الأنابيب" ؛ وسيقوم "دفق إخراج الأنابيب" بنقل البيانات إلى "دفق إدخال الأنابيب" ، أي أنه سيتم حفظه في المخزن المؤقت لـ "دفق إدخال الأنابيب".
بعد ذلك ، ننظر إلى "كيف يقرأ المستخدمون البيانات من المخزن المؤقت لـ" دفق إدخال الأنابيب "". هذا هو في الواقع عمل مؤشر ترابط المتلقي.
سيبدأ T2.start () مؤشر ترابط المتلقي ، وبالتالي تنفيذ وظيفة Receiver.java Run (). بالنظر إلى رمز المصدر لـ receiver.java ، نعلم أن Run () يستدعي readMessageOnce ().
يجب على readMessageOnce () الاتصال بـ. READ (BUF) لقراءة البيانات من "دفق إدخال الأنابيب في" وحفظه إلى BUF.
من خلال التحليل أعلاه ، نعلم بالفعل أن البيانات الموجودة في المخزن المؤقت لـ "دفق إدخال الأنابيب في" هي "هذه رسالة قصيرة" ؛ لذلك ، فإن بيانات BUF هي "هذه رسالة قصيرة".
من أجل تعميق فهم خط الأنابيب. سنواصل التجربتين الصغيرتين التاليتين.
التجربة 1: تعديل sender.java
سوف
public void run () {writeShortMessage () ؛ // writelongmessage () ؛} تعديل ل
public void run () {// writeShortMessage () ؛ WriteLongMessage () ؛} تشغيل البرنامج. النتيجة الجارية هي:
تتم كتابة هذه البيانات إلى "دفق إخراج الأنابيب" من خلال WriteLongMessage () ، ثم نقلها إلى "دفق إدخال الأنابيب" ، ثم تخزينها في المخزن المؤقت لـ "دفق إدخال الأنابيب" ؛ ثم اقرأ من المخزن المؤقت من قبل المستخدم.
ثم ، راقب رمز المصدر للكتابة (). يمكننا أن نجد أن طول STR هو 1046 بايت ، ثم نتيجة الجري هي فقط 1024 بايت! لماذا هذا يحدث؟
السبب بسيط: الحجم الافتراضي للمخزن المؤقت لتيار إدخال خط الأنابيب هو 1024 بايت. لذلك ، على الأكثر ، يمكن كتابة 1024 بايت.
من خلال مراقبة الكود المصدري لـ pipedInputStream.java ، يمكننا أن نفهم بشكل أكثر شمولية.
int static int int default_pipe_size = 1024 ؛ pipedInputStream () {initPipe (default_pipe_size) ؛} يستدعي المنشئ الافتراضي initPipe (default_pipe_size) ، ورمز المصدر الخاص به على النحو التالي:
private void initPipe (int pipesize) {if (pipesize <= 0) {رمي جديد alfictalargumentException ("حجم الأنابيب <= 0") ؛ } buffer = new byte [pipesize] ؛} من هذا ، يمكننا أن نعرف أن الحجم الافتراضي للمخزن المؤقت هو 1024 بايت.
التجربة 2: استمر في تعديل جهاز الاستقبال. جافا على أساس "التجربة 1"
سوف
public void run () {readMessageOnce () ؛ // readMessageContinued () ؛} تعديل ل
public void run () {// readMessageOnce () ؛ ReadMessageContinued () ؛} تشغيل البرنامج. النتيجة الجارية هي:
هذه النتيجة هي البيانات الكاملة المكتوبة إلى "المخزن المؤقت للإدخال".
pipedwriter و pipedreader
PipedWriter هو دفق إخراج خط أنابيب حرف ، ورثه من الكاتب.
PipedReader هو دفق إدخال خط أنابيب حرف يرث من الكاتب.
وظيفة مؤلف الأنابيب و PipedReader هي التواصل بين المواضيع من خلال خطوط الأنابيب. عند استخدام اتصال خطوط الأنابيب ، يجب استخدام PipedWriter و PipedReader بالاقتران مع بعضهما البعض.
أدناه ، ننظر إلى أمثلة على الاتصال من خلال PipedWriter و PipedReader في MultiThreading. وتشمل الأمثلة 3 فئات: receiver.java ، sender.java و pipetest.java
مدونة المتلقي. جافا كما يلي:
استيراد java.io.ioException ؛ استيراد java.io.pipedreader ؛ suppressWarnings ("All") / *** مؤشر ترتيب المتلقي* / جهاز استقبال الفئة العامة يمتد كائن دفق إدخال خط أنابيب. // يرتبط بكائن "pipedwriter" ، // هذا يتيح لك استلام بيانات "pipedwriter" ثم دع المستخدم يقرأه. PipedReader الخاص في = New PipedReader () ؛ // احصل على "كائن دفق إدخال الأنابيب" pipedreader getReader () {return in ؛ } Override public void run () {readMessageOnce () ؛ // readMessageContinued () ؛ } // اقرأ البيانات مرة واحدة من "دفق إدخال الأنابيب" public void readMessageOnce () {// على الرغم من أن حجم BUF هو 2048 حرفًا ، إلا أنه سيقرأ فقط 1024 حرفًا من "دفق إدخال الأنابيب". // لأن حجم المخزن المؤقت لـ "دفق إدخال الأنابيب" هو 1024 حرفًا فقط بشكل افتراضي. char [] buf = new Char [2048] ؛ حاول {int len = in.read (buf) ؛ System.out.println (سلسلة جديدة (buf ، 0 ، len)) ؛ in.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} // عند القراءة> 1024 أحرف من "دفق إدخال الأنابيب" ، توقف عن قراءة الفراغ العام readMessageContinued () {int total = 0 ؛ بينما (صحيح) {char [] buf = new char [1024] ؛ حاول {int len = in.read (buf) ؛ المجموع += لين ؛ System.out.println (سلسلة جديدة (buf ، 0 ، len)) ؛ // إذا كان العدد الإجمالي للقراءة هو> 1024 ، فسيتم خروج الحلقة. إذا (المجموع> 1024) استراحة ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} حاول {in.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} رمز المرسل. جافا كما يلي:
استيراد java.io.ioException ؛ استيراد java.io.pipedWriter ؛ suppressWarnings ("All")/ *** Sender Thread*/ Sender الفئة العامة يمتد مؤشر ترابط {// أنابيب خط إخراج كائن. // يرتبط بكائن "PipedReader" ، // هذا يسمح بإرسال البيانات إلى بيانات "PipedReader" ويمكن للمستخدم قراءة البيانات من "PipedReader". pipedwriter الخاص خارج = New PipedWriter () ؛ // احصل على "دفق إخراج الأنابيب" كائن PipedWriter GetWriter () {return Out ؛ } Override public void run () {writeShortMessage () ؛ // writelongmessage () ؛ } // اكتب رسالة قصيرة إلى "دفق إخراج الأنابيب": "هذه رسالة قصيرة" private void writeShortMessage () {String strinfo = "هذه رسالة قصيرة" ؛ حاول {out.write (strinfo.tochararray ()) ؛ out.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }} // اكتب رسالة طويلة إلى "دفق إخراج الأنابيب" private void writeLongMessage () {StringBuilder sb = new StringBuilder () ؛ // اكتب 1020 حرفًا من خلال حلقة لـ (int i = 0 ؛ i <102 ؛ i ++) sb.append ("0123456789") ؛ // اكتب 26 حرفًا أكثر. SB.Append ("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ؛ // الطول الإجمالي لـ STR هو 1020+26 = 1046 أحرف String STR = SB.ToString () ؛ جرب {// اكتب 1046 حرفًا في "دفق إخراج الأنابيب" Out.write (str) ؛ out.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} رمز pipetest.java كما يلي:
استيراد java.io.pipedreader ؛ استيراد java.io.pipedwriter ؛ استيراد java.io.ioException ؛ suppressWarnings ("All") / *** البرنامج التفاعلي لدفق إدخال خط الأنابيب ودفق خط الأنابيب* / Public Classeest {public static void main (string) {sender t1 = new sender () ؛ جهاز الاستقبال T2 = جهاز استقبال جديد () ؛ pipedwriter out = t1.getWriter () ؛ PipedReader في = t2.getReader () ؛ جرب {// connection. جوهر الجملتين التاليتين هو نفسه. //out.connect(in) ؛ in.connect (out) ؛ /** * ابدأ طريقة فئة مؤشر الترابط: * اجعل مؤشر الترابط يبدأ في التنفيذ ؛ يستدعي جهاز Java Virtual طريقة تشغيل مؤشر الترابط. * النتيجة هي أن خيطين يعملان بشكل متزامن ؛ مؤشر الترابط الحالي (تم إرجاعه من المكالمة إلى طريقة البدء) والموضوع الآخر (تنفيذ طريقة التشغيل الخاصة به). * من غير القانوني بدء موضوع عدة مرات. خاصة عندما ينتهي الخيط من التنفيذ ، لا يمكن إعادة تشغيله. */ t1.start () ؛ t2.start () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}} نتائج التشغيل:
هذه رسالة قصيرة
وصف النتائج:
(1)
in.connect (out) ؛
تتمثل وظيفتها في ربط "دفق إدخال الأنابيب" و "دفق إخراج الأنابيب". تحقق من رمز المصدر للاتصال () في pipedWriter.java و pipedReader.java ؛ نحن نعرف Out.connect (in) ؛ يعادل in.connect (out) ؛
(2)
t1.start () ؛ // ابدأ مؤشر ترابط "المرسل" t2.start () ؛ // ابدأ موضوع "المتلقي"
تحقق أولاً من رمز المصدر لـ Sender.java ، وقم بتنفيذ وظيفة Run () بعد بدء تشغيل الخيط ؛ في Run () of sender.java ، اتصل بـ WriteShortMessage () ؛
وظيفة WriteShortMessage () ؛ هو كتابة البيانات "هذه رسالة قصيرة" إلى "دفق إخراج الأنابيب" ؛ سيتم استلام هذه البيانات بواسطة "دفق إدخال الأنابيب". دعونا نرى كيف يتم تحقيق ذلك.
دعونا أولاً نلقي نظرة على رمز المصدر للكتابة (char char. pipedwriter.java يرث من الكاتب. java ؛ رمز المصدر للكتابة (char c []) في الكاتب. جافا كما يلي:
كتابة الفراغ العام (char cbuf []) يلقي ioException {write (cbuf ، 0 ، cbuf.length) ؛}
في الواقع ، اكتب (char c []) هي وظيفة كتابة المكالمة (char c [] ، int Off ، int len) في pipedwriter.java. عند النظر إلى رمز الكتابة المصدر (char c [] ، int Off ، int len) ، وجدنا أنه سيتصل بالوعة. receive (cbuf ، Off ، Len) ؛ كذلك النظر في تعريف الاستقبال (char c [] ، int fut ، int len) ، نحن نعلم أن Sink.Receive (cbuf ، Off ، LEN) هو حفظ البيانات في "دفق إخراج الأنابيب" في المخزن المؤقت لـ "دفق إدخال الأنابيب". الحجم الافتراضي للمخزن المؤقت لـ "دفق إدخال الأنابيب" هو 1024 حرفًا.
في هذه المرحلة ، نعلم أن: t1.start () يبدأ مؤشر ترابط المرسل ، وسيقوم مؤشر ترابط المرسل بكتابة البيانات "هذه رسالة قصيرة" إلى "دفق إخراج الأنابيب" ؛ وسيقوم "دفق إخراج الأنابيب" بنقل البيانات إلى "دفق إدخال الأنابيب" ، أي أنه سيتم حفظه في المخزن المؤقت لـ "دفق إدخال الأنابيب".
بعد ذلك ، ننظر إلى "كيف يقرأ المستخدمون البيانات من المخزن المؤقت لـ" دفق إدخال الأنابيب "". هذا هو في الواقع عمل مؤشر ترابط المتلقي.
سيبدأ T2.start () مؤشر ترابط المتلقي ، وبالتالي تنفيذ وظيفة Receiver.java Run (). بالنظر إلى رمز المصدر لـ receiver.java ، نعلم أن Run () يستدعي readMessageOnce ().
يجب على readMessageOnce () الاتصال بـ. READ (BUF) لقراءة البيانات من "دفق إدخال الأنابيب في" وحفظه إلى BUF.
من خلال التحليل أعلاه ، نعلم بالفعل أن البيانات الموجودة في المخزن المؤقت لـ "دفق إدخال الأنابيب في" هي "هذه رسالة قصيرة" ؛ لذلك ، فإن بيانات BUF هي "هذه رسالة قصيرة".
من أجل تعميق فهم خط الأنابيب. سنواصل التجربتين الصغيرتين التاليتين.
التجربة 1: تعديل sender.java
سوف
public void run () {writeShortMessage () ؛ // writelongmessage () ؛} تعديل ل
public void run () {// writeShortMessage () ؛ WriteLongMessage () ؛} تشغيل البرنامج. نتائج التشغيل كما يلي:
من هذا ، يمكننا أن نرى أن البرنامج يعمل بشكل غير صحيح! رمي الاستثناء java.io.ioException: أنبوب مغلق
لماذا هذا يحدث؟
سأحلل تدفق البرنامج.
(1) في الأنابيب ، قم بتوصيل خطوط أنابيب الإدخال والإخراج من خلال in.connect (out) ؛ ثم ، ابدأ اثنين من المواضيع. T1.start () يبدأ مرسل مؤشر الترابط ، ويبدأ T2.start () جهاز استقبال مؤشر الترابط.
(2) بعد بدء تشغيل مؤشر ترابط المرسل ، تتم كتابة البيانات إلى "خط أنابيب الإخراج" من خلال WriteLongMessage () ، و Out.Write (str.tocharray ()) يكتب ما مجموعه 1046 حرفًا. وفقًا لرمز المصدر لـ PipedWriter ، ستتصل وظيفة Write () لـ PipedWriter بوظيفة RESER () لـ PIPEDREADER. بالنظر إلى وظيفة استقبال () من PipedReader ، نعلم أن PipedReader سيقوم بتخزين المخزن المؤقت للبيانات المقبولة. إذا لاحظت وظيفة RESER () بعناية ، فهناك الرمز التالي:
بينما (in == out) {if ((readside! = null) &&! readside.isalive ()) {رمي iOexception جديد ("pipe broken") ؛ } / * ممتلئ: ركلة أي قراء انتظار * / eletyall () ؛ حاول {انتظر (1000) ؛ } catch (interruptedException ex) {throw new Java.io.InterrededioException () ؛ }} القيم الأولية للداخل والخارج في = -1 ، Out = 0 ، على التوالي ؛ جنبا إلى جنب مع ما سبق بينما (في == OUT). نحن نعلم أن معناها هو أنه في كل مرة يتم فيها كتابة شخصية في خط الأنابيب ، يتم استيفاء الحالة في == Out. بعد ذلك ، يتم استدعاء إخطار () لإيقاظ "الخيط الذي يقرأ خط الأنابيب".
أي في كل مرة يتم فيها كتابة شخصية في خط الأنابيب ، فإنها ستمنع وانتظار قراءة مؤشرات الترابط الأخرى.
ومع ذلك ، فإن الحجم الافتراضي للمخزن المؤقت لـ PipedReader هو 1024! ومع ذلك ، هناك 1046 بيانات ليتم كتابتها في هذا الوقت! لذلك ، يمكن كتابة 1024 حرفًا على الأكثر في وقت واحد.
(03) بعد بدء تشغيل مؤشر ترتيب المتلقي ، سيتم استدعاء ReadMessageOnce () لقراءة دفق إدخال خط الأنابيب. سيتم قراءة 1024 حرفًا ، وسيتم استدعاء Close () لإغلاق الأنابيب.
من تحليل (02) و (03) ، يمكن ملاحظة أن المرسل يحتاج إلى كتابة 1046 حرفًا في خط الأنابيب. من بينها ، يمكن كتابة أول 1024 حرفًا (سعة المخزن المؤقت 1024) بشكل طبيعي ، ويتم قراءة واحدة لكل كتابة. عند كتابة 1025 حرفًا ، لا يزال يتم استدعاء contract () في pipedwriter.java بالتسلسل ؛ ثم ، تسمى () في pipedreader.java ؛ في pipedreader.java ، سيتم في النهاية استدعاء وظيفة استلام (int c). في هذا الوقت ، تم إغلاق تيار إدخال خط الأنابيب ، أي أن AckedByReader صحيح ، لذلك يتم إلقاء ioException ("الأنابيب مغلقة").
نواصل تعديل "اختبار واحد" لحل المشكلة.
التجربة 2: استمر في تعديل جهاز الاستقبال. جافا على أساس "التجربة 1".
public void run () {readMessageOnce () ؛ // readMessageContinued () ؛} تعديل ل
public void run () {// readMessageOnce () ؛ ReadMessageContinued () ؛} في هذا الوقت ، يمكن للبرنامج تشغيل بشكل طبيعي. النتيجة الجارية هي: