من فضلك تسجيل الدخول أو تسجيل لتفعل ذلك.

مقدمة

تسلط هذه المقالة الضوء على المهام التي من المرجح أن يواجهها مبرمجو التطبيقات، وخاصة في تطبيقات الويب، مثل:

  • قراءة وكتابة ملفات نصية
  • قراءة النصوص والصور وJSON من الويب
  • زيارة الملفات الموجودة في الدليل
  • قراءة ملف ZIP
  • إنشاء ملف أو دليل مؤقت

تدعم واجهة برمجة تطبيقات Java العديد من المهام الأخرى، والتي يتم شرحها بالتفصيل في برنامج تعليمي حول واجهة برمجة تطبيقات الإدخال والإخراج في Java.

تسلط هذه المقالة الضوء على تحسينات واجهة برمجة التطبيقات منذ إصدار Java 8. وبشكل خاص:

  • UTF-8 هو الإعداد الافتراضي للإدخال والإخراج منذ Java 18 (منذ JEP 400: UTF-8 افتراضيًا)
  • ال java.nio.file.Files الفئة، التي ظهرت لأول مرة في Java 7، أضافت طرقًا مفيدة في Java 8 و11 و12
  • java.io.InputStream اكتسبت طرقًا مفيدة في Java 9 و11 و12
  • ال java.io.File و java.io.BufferedReader أصبحت الفصول الدراسية الآن قديمة تمامًا، على الرغم من ظهورها بشكل متكرر في عمليات البحث على الويب ومحادثات الذكاء الاصطناعي.

قراءة ملفات النصوص

يمكنك قراءة ملف نصي إلى سلسلة مثل هذا:

String content=Files.readString(path);

هنا، path هو مثال على java.nio.Path، تم الحصول عليها على هذا النحو:

var path=Path.of("/usr/share/dict/words");

قبل Java 18، كان من المستحسن بشدة تحديد ترميز الأحرف مع أي عمليات ملفات تقرأ أو تكتب سلاسل. في الوقت الحاضر، يعد ترميز الأحرف الأكثر شيوعًا هو UTF-8، ولكن من أجل التوافق مع الإصدارات السابقة، استخدمت Java “ترميز النظام الأساسي”، والذي يمكن أن يكون ترميزًا قديمًا على Windows. لضمان قابلية النقل، كانت عمليات إدخال/إخراج النص بحاجة إلى معلمات StandardCharsets.UTF_8. هذا لم يعد ضروريا.

إذا كنت تريد الملف كسلسلة من الأسطر، فاتصل بـ

List lines=Files.readAllLines(path);

إذا كان الملف كبيرًا، قم بمعالجة الأسطر ببطء كـ Stream:

try (Stream lines=Files.lines(path)) {    . . .}

أيضا استخدام Files.lines إذا كان بإمكانك معالجة الخطوط بشكل طبيعي باستخدام عمليات التدفق (مثل map, filter). لاحظ أن الدفق الذي تم إرجاعه بواسطة Files.lines يجب إغلاقه. للتأكد من حدوث ذلك، استخدم حاول استخدام الموارد العبارة، كما هو الحال في مقتطف التعليمات البرمجية السابق.

لم يعد هناك سبب وجيه لاستخدام readLine طريقة java.io.BufferedReader.

لتقسيم مدخلاتك إلى شيء آخر غير الأسطر، استخدم java.util.Scannerعلى سبيل المثال، إليك كيفية قراءة الكلمات، مفصولة بأحرف غير مترابطة:

Stream tokens=new Scanner(path).useDelimiter("\PL+").tokens();

ال Scanner تحتوي الفئة أيضًا على طرق لقراءة الأرقام، ولكن من الأسهل عمومًا قراءة المدخلات كسلسلة واحدة لكل سطر، أو سلسلة واحدة، ثم تحليلها.

كن حذرًا عند تحليل الأرقام من ملفات نصية، حيث قد يعتمد تنسيقها على الموقع المحلي. على سبيل المثال، قد يكون ملف الإدخال 100.000 100.0 في الإعدادات المحلية للولايات المتحدة ولكن 100000.0 في الإعدادات المحلية الألمانية. استخدم java.text.NumberFormat للتحليل المحلي المحدد. بدلاً من ذلك، قد تتمكن من استخدام Integer.parseInt/Double.parseDouble.

كتابة ملفات نصية

يمكنك كتابة سلسلة إلى ملف نصي بمكالمة واحدة:

String content=. . .;Files.writeString(path, content);

إذا كان لديك قائمة من الأسطر بدلاً من سلسلة واحدة، استخدم:

List lines=. . .;Files.write(path, lines);

للحصول على نتائج أكثر عمومية، استخدم PrintWriter إذا كنت تريد استخدام printf طريقة:

var writer=new PrintWriter(path.toFile());writer.printf(locale, "Hello, %s, next year you'll be %d years old!%n", name, age + 1);

لاحظ أن printf يعتمد على الموقع. عند كتابة الأرقام، تأكد من كتابتها بالتنسيق المناسب. بدلاً من استخدام printf، يعتبر java.text.NumberFormat أو Integer.toString/Double.toString.

من الغريب أنه اعتبارًا من Java 21، لا يوجد PrintWriter منشئ مع Path معامل.

إذا لم تستخدم printf، يمكنك استخدام ال BufferedWriter الصف وكتابة السلاسل باستخدام write طريقة.

var writer=Files.newBufferedWriter(path);writer.write(line); // Does not write a line separatorwriter.newLine(); 

تذكر أن تغلق writer عندما تنجز.

القراءة من مجرى الإدخال

ربما يكون السبب الأكثر شيوعًا لاستخدام الدفق هو قراءة شيء ما من موقع ويب.

إذا كنت بحاجة إلى تعيين رؤوس الطلب أو قراءة رؤوس الاستجابة، فاستخدم HttpClient:

HttpClient client=HttpClient.newBuilder().build();HttpRequest request=HttpRequest.newBuilder()    .uri(URI.create("https://horstmann.com/index.html"))    .GET()    .build();HttpResponse response=client.send(request, HttpResponse.BodyHandlers.ofString());String result=response.body();

هذا أمر مبالغ فيه إذا كان كل ما تريده هو البيانات. بدلاً من ذلك، استخدم:

InputStream in=new URI("https://horstmann.com/index.html").toURL().openStream();

ثم اقرأ البيانات في مصفوفة بايتات وقم بتحويلها اختياريًا إلى سلسلة:

byte[] bytes=in.readAllBytes();String result=new String(bytes);

أو نقل البيانات إلى مجرى الإخراج:

OutputStream out=Files.newOutputStream(path);in.transferTo(out);

لاحظ أنه لا يلزم وجود حلقة إذا كنت تريد ببساطة قراءة كافة بايتات مجرى الإدخال.

ولكن هل تحتاج حقًا إلى تدفق إدخال؟ تتيح لك العديد من واجهات برمجة التطبيقات خيار القراءة من ملف أو عنوان URL.

من المرجح أن تحتوي مكتبة JSON المفضلة لديك على طرق للقراءة من ملف أو عنوان URL. على سبيل المثال، مع جاكسون جونيور:

URL url=new URI("https://dog.ceo/api/breeds/image/random").toURL();Map result=JSON.std.mapFrom(url);

إليك كيفية قراءة صورة الكلب من المكالمة السابقة:

URL url=new URI(result.get("message").toString()).toURL();BufferedImage img=javax.imageio.ImageIO.read(url);

هذا أفضل من تمرير دفق الإدخال إلى read الطريقة، لأن المكتبة يمكنها استخدام معلومات إضافية من عنوان URL لتحديد نوع الصورة.

واجهة برمجة التطبيقات للملفات

ال java.nio.file.Files توفر الفئة مجموعة شاملة من عمليات الملفات، مثل إنشاء الملفات والدلائل ونسخها ونقلها وحذفها. أساسيات نظام الملفات يوفر البرنامج التعليمي وصفًا شاملاً. في هذا القسم، أسلط الضوء على بعض المهام الشائعة.

التنقل بين الإدخالات في الدلائل والدلائل الفرعية

في معظم المواقف، يمكنك استخدام إحدى الطريقتين. Files.list تقوم الطريقة بزيارة جميع الإدخالات (الملفات، الدلائل الفرعية، الروابط الرمزية) الخاصة بالدليل.

try (Stream entries=Files.list(pathToDirectory)) {    . . .}

إستخدم حاول استخدام الموارد عبارة للتأكد من أن كائن التدفق، الذي يتتبع التكرار، سيتم إغلاقه.

إذا كنت تريد أيضًا زيارة إدخالات الدلائل الفرعية، فاستخدم بدلاً من ذلك الطريقة Files.walk

Stream entries=Files.walk(pathToDirectory);

ثم استخدم ببساطة طرق التدفق للتركيز على الإدخالات التي تهمك، وجمع النتائج:

try (Stream entries=Files.walk(pathToDirectory)) {    List htmlFiles=entries.filter(p -> p.toString().endsWith("html")).toList();    . . .}

وفيما يلي الطرق الأخرى لاجتياز إدخالات الدليل:

  • نسخة محملة من Files.walk يتيح لك تحديد عمق الشجرة التي تم عبورها.
  • اثنين Files.walkFileTree توفر الأساليب مزيدًا من التحكم في عملية التكرار، من خلال إخطار FileVisitor عند زيارة دليل للمرة الأولى والأخيرة. قد يكون هذا مفيدًا في بعض الأحيان، وخاصةً لتفريغ وحذف شجرة من الدلائل. راجع البرنامج التعليمي المشي على شجرة الملف للحصول على التفاصيل. ما لم تكن بحاجة إلى هذا التحكم، استخدم أبسط Files.walk طريقة.
  • ال Files.find الطريقة هي تماما مثل Files.walkولكنك توفر مرشحًا يفحص كل مسار ومساره. BasicFileAttributesيعد هذا أكثر كفاءة إلى حد ما من قراءة السمات بشكل منفصل لكل ملف.
  • اثنين Files.newDirectoryStream(Path) الأساليب تنتج DirectoryStream الحالات التي يمكن استخدامها في تحسين for الحلقات. لا توجد ميزة في استخدام Files.list.
  • الإرث File.list أو File.listFiles الأساليب ترجع أسماء الملفات أو File الأشياء. هذه الأشياء أصبحت قديمة الآن.

العمل مع ملفات ZIP

منذ إصدار Java 1.1، ZipInputStream و ZipOutputStream توفر الفئات واجهة برمجة تطبيقات لمعالجة ملفات ZIP. لكن واجهة برمجة التطبيقات غير سلسة بعض الشيء. قدمت Java 8 واجهة برمجة تطبيقات أفضل كثيرًا نظام الملفات ZIP:

try (FileSystem fs=FileSystems.newFileSystem(pathToZipFile)) {    . . .}

ال حاول استخدام الموارد يضمن البيان أن close يتم استدعاء الطريقة بعد عمليات ملف ZIP. تقوم هذه الطريقة بتحديث ملف ZIP ليعكس أي تغييرات في نظام الملفات.

يمكنك بعد ذلك استخدام أساليب Files الصف. هنا نحصل على قائمة بجميع الملفات الموجودة في ملف ZIP:

try (Stream entries=Files.walk(fs.getPath("/"))) {    List filesInZip=entries.filter(Files::isRegularFile).toList();}

لقراءة محتويات الملف، استخدم فقط Files.readString أو Files.readAllBytes:

String contents=Files.readString(fs.getPath("/LICENSE"));

يمكنك إزالة الملفات باستخدام Files.deleteلإضافة أو استبدال الملفات، استخدم ببساطة Files.writeString أو Files.write.

إنشاء الملفات والدلائل المؤقتة

في كثير من الأحيان، أحتاج إلى جمع مدخلات المستخدم وإنتاج ملفات وتشغيل عملية خارجية. ثم أستخدم ملفات مؤقتة، والتي تختفي بعد إعادة التشغيل التالية، أو دليل مؤقت أقوم بمسحه بعد اكتمال العملية.

أستخدم الطريقتين Files.createTempFile و Files.createTempDirectory من أجل هذا.

Path filePath=Files.createTempFile("myapp", ".txt");Path dirPath=Files.createTempDirectory("myapp");

يؤدي هذا إلى إنشاء ملف أو دليل مؤقت في موقع مناسب (/tmp في Linux) بالبادئة المحددة، وبالنسبة للملف، اللاحقة.

خاتمة

قد تقترح عمليات البحث على الويب والمحادثات عبر الذكاء الاصطناعي أكوادًا معقدة لا داعي لها لعمليات الإدخال/الإخراج الشائعة. غالبًا ما توجد بدائل أفضل:

  1. لا تحتاج إلى حلقة لقراءة أو كتابة السلاسل أو مصفوفات البايتات.
  2. ربما لا تحتاج حتى إلى دفق أو قارئ أو كاتب.
  3. تعرف على Files طرق إنشاء الملفات والدلائل ونسخها ونقلها وحذفها.
  4. يستخدم Files.list أو Files.walk للتنقل بين إدخالات الدليل.
  5. استخدم نظام ملفات ZIP لمعالجة ملفات ZIP.
  6. ابتعد عن الإرث File فصل.

اقرأ أكثر

ارتفاع أرباح وإيرادات AWS مع تخطيط عملاق الحوسبة السحابية العامة للاستثمار في البنية التحتية للذكاء الاصطناعي
وزارة العدل الأمريكية تقاضي تيك توك بسبب انتهاكات مزعومة لخصوصية الأطفال

Reactions

0
0
0
0
0
0
بالفعل كان رد فعل لهذا المنصب.

ردود الفعل