مرحبًا يا من هناك! كمورد لـ NIO، لقد تعمقت في عالم الإدخال/الإخراج غير المتزامن لـ Java NIO، واليوم يسعدني أن أشارككم كيفية استخدام CompletionHandler في الإدخال/الإخراج غير المتزامن لـ Java NIO. إنه مفهوم رائع جدًا يمكنه رفع مستوى لعبة البرمجة الخاصة بك، خاصة عند التعامل مع عمليات الإدخال/الإخراج عالية الأداء.
أولاً، دعونا نفهم ما هو كل ما يتعلق بالإدخال/الإخراج غير المتزامن لـ Java NIO. في Java I/O التقليدية، يتم حظر العمليات. وهذا يعني أنه عندما تقوم بعملية إدخال/إخراج مثل القراءة من ملف أو الحصول على البيانات من مقبس الشبكة، يجب على برنامجك الانتظار حتى تنتهي هذه العملية قبل أن يتمكن من الانتقال إلى المهمة التالية. يمكن أن يكون هذا عائقًا حقيقيًا، خاصة في التطبيقات ذات حركة المرور العالية حيث لا تريد أن يظل برنامجك عالقًا في الانتظار.
من ناحية أخرى، يسمح الإدخال/الإخراج غير المتزامن لـ Java NIO لبرنامجك بمواصلة القيام بمهام أخرى أثناء تقدم عملية الإدخال/الإخراج. يستخدم أسلوب رد الاتصال أو القائم على المستقبل لإعلام البرنامج الخاص بك عند اكتمال العملية. وهنا يأتي دور CompletionHandler.
CompletionHandler عبارة عن واجهة في Java NIO تحدد طريقتين:مكتملوفشل. المكتمليتم استدعاء الطريقة عند انتهاء عملية الإدخال/الإخراج غير المتزامنة بنجاح، وتتيح لك الوصول إلى نتيجة العملية. الفشليتم استدعاء الطريقة إذا حدث خطأ ما أثناء العملية، وتوفر معلومات حول الخطأ.
لنبدأ بمثال بسيط لاستخدام CompletionHandler لقراءة الملفات غير المتزامنة.
import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.CompletionHandler; import java.nio.file.Path; استيراد java.nio.file.Paths؛ import java.nio.file.StandardOpenOption; public class AsyncFileReadExample { public static void main(String[] args) { Path path = Paths.get("test.txt"); حاول (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void Complete(Integer result, ByteBuffer Attachment) { System.out.println("Read " + result + " bytes"); buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new) String(data)); } @Override public void Fail(Throwable exc, ByteBuffer Attachment) { System.err.println("فشلت القراءة: " + exc.getMessage() } }); // قم بمهام أخرى أثناء عملية القراءة System.out.println("القيام بمهام أخرى..."); Thread.sleep(2000); } Catch (Exception e) { e.printStackTrace(); } } }
في هذا المثال، نقوم أولاً بفتح ملفAsynchronousFileChannelللقراءة. ثم نخصص أByteBufferللاحتفاظ بالبيانات التي سنقرأها. نحن نسمييقرأالطريقة على قناة الملف، والتمرير في المخزن المؤقت، والموضع الذي تبدأ القراءة منه (في هذه الحالة، 0)، والمرفق (الذي يمكن أن يكون أي كائن تريد تمريره مع العملية)، ومثيل لديناCompletionHandler.


المكتملالطريقة فيCompletionHandlerيتم استدعاؤه عند نجاح عملية القراءة. فهو يطبع عدد البايتات المقروءة، ويقلب المخزن المؤقت، ثم يطبع محتويات المخزن المؤقت كسلسلة. الفشليتم استدعاء الطريقة إذا حدث خطأ أثناء عملية القراءة، وتطبع رسالة خطأ.
أثناء استمرار عملية القراءة، يمكن لبرنامجنا الاستمرار في القيام بمهام أخرى. في هذا المثال البسيط، نقوم فقط بطباعة رسالة ثم ننام لبضع ثوان.
الآن، دعونا نتحدث عن استخدام CompletionHandler للإدخال/الإخراج للشبكة. لنفترض أنك تقوم بإنشاء تطبيق عميل - خادم، وتريد التعامل مع الاتصالات الواردة بشكل غير متزامن.
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class AsyncServerExample { public static void main(String[] args) { حاول (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) { serverSocketChannel.bind(new InetSocketAddress(8080)); System.out.println("بدأ الخادم على المنفذ 8080"); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void Complete(AsynchronousSocketChannel clientChannel, Void Attachment) { serverSocketChannel.accept(null, this); System.out.println("عميل جديد متصل"); ByteBuffer buffer = ByteBuffer.allocate(1024); clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public voidCompleted(Integer result, ByteBuffer Attachment) { if (result > 0) { Attachment.flip(); byte[] data = new byte[attachment.limit()]; Attachment.get(data); String message = new String(data); System.out.println("تم الاستلام: " + message); حاول {clientChannel.write(ByteBuffer.wrap("لقد أرسلت: "+ message).getBytes()).get(); } Catch (Exception e) { e.printStackTrace(); } } حاول {clientChannel. Close() } Catch (IOException e) { e.printStackTrace() } } @Override public void Fail(Throwable exc, ByteBuffer Attachment) { System.err.println("فشلت القراءة: " + exc.getMessage()); حاول {clientChannel.cloud(); } Catch (IOException e) { e.printStackTrace(); } } }); // استمر في تشغيل الخادم Thread.sleep(Long.MAX_VALUE); } Catch (Exception e) { e.printStackTrace(); } } }
في مثال الخادم هذا، نقوم بفتح ملفAsynchronousServerSocketChannelوربطه بالمنفذ 8080. ثم نسميهيقبلالطريقة على قناة مأخذ الخادم، ويمر فيCompletionHandler. عندما يتصل عميل جديد،مكتملطريقةCompletionHandlerيسمى. داخل هذه الطريقة، نقبل اتصالاً آخر (حتى يتمكن الخادم من التعامل مع عملاء متعددين)، ونطبع رسالة تشير إلى اتصال عميل جديد، ثم نبدأ في قراءة البيانات من العميل.
نحن نستخدم آخرCompletionHandlerلعملية القراءة. إذا تمت القراءة بنجاح، نقوم بطباعة الرسالة المستلمة وإرسال الرد مرة أخرى إلى العميل. إذا كان هناك خطأ، فإننا نطبع رسالة خطأ ونغلق قناة العميل.
أحد الأشياء الرائعة في استخدام CompletionHandler في الإدخال/الإخراج غير المتزامن لـ Java NIO هو أنه يسمح لك بمعالجة عمليات الإدخال/الإخراج المتعددة بشكل متزامن دون حظر برنامجك. يمكن أن يؤدي هذا إلى تطبيقات أكثر كفاءة واستجابة، خاصة في السيناريوهات التي يكون لديك فيها عدد كبير من العملاء أو عمليات نقل بيانات كبيرة الحجم.
إذا كنت من محبي السيارات الكهربائية، فقد تكون مهتمًا بـسيارة كهربائية نيو ET5. إنها سيارة كهربائية أنيقة وعالية الأداء تجمع بين الأسلوب والتكنولوجيا، تمامًا مثل الطريقة التي يجمع بها CompletionHandler بين الكفاءة والمرونة في Java NIO I/O غير المتزامن.
باعتباري أحد موردي NIO، فأنا أعلم أهمية الأنظمة الموثوقة وعالية الأداء. سواء كان الأمر في صناعة السيارات أو في برمجة البرمجيات، فإننا نبحث دائمًا عن طرق للتحسين والتحسين. إذا كنت مهتمًا بمعرفة المزيد حول الإدخال/الإخراج غير المتزامن لـ Java NIO أو لديك أي احتياجات تتعلق بمنتجاتنا وخدماتنا، فلا تتردد في التواصل معنا. نحن هنا لمساعدتك في الارتقاء بمشاريعك إلى المستوى التالي. دعنا نجري محادثة حول كيفية العمل معًا لتلبية متطلباتك.
مراجع:
- وثائق جافا NIO
- العديد من دروس البرمجة والمدونات عبر الإنترنت



























































