سؤال

أحاول إخراج ملف نصي إلى وحدة التحكم مع Java. كنت أتساءل ما هي الطريقة الأكثر فعالية للقيام بذلك؟

لقد بحثت في العديد من الطرق ، ومع ذلك ، من الصعب تمييز ما هو الحل الأقل تأثرًا بالأداء.

سيتضمن إخراج ملف نصي إلى وحدة التحكم القراءة في كل سطر في الملف ، ثم كتابته إلى وحدة التحكم.

هل من الأفضل استخدام:

  1. قارئ مخزنة مع قائد fileReader ، القراءة في خطوط والقيام مجموعة من system.out.println المكالمات؟

    BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\")); 
    while (in.readLine() != null) {
          System.out.println(blah blah blah);          
    }         
    in.close();
    
  2. الماسح الضوئي قراءة كل سطر في الملف والقيام بالمكالمات system.print؟

    while (scanner.hasNextLine()) { 
        System.out.println(blah blah blah);   
    }
    

شكرًا.

هل كانت مفيدة؟

المحلول

إذا لم تكن مهتمًا بالبيانات المستندة إلى الأحرف ، فإن الملف النصي يحتوي عليه ، فما عليك سوى دفقه "RAW" كبايت.

InputStream input = new BufferedInputStream(new FileInputStream("C:/logs.txt"));
byte[] buffer = new byte[8192];

try {
    for (int length = 0; (length = input.read(buffer)) != -1;) {
        System.out.write(buffer, 0, length);
    }
} finally {
    input.close();
}

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

بالنسبة للأداء ، قد تجد هذه المقالة مثير للإعجاب. وفقا للمقال ، أ FileChannel مع صفيف بايت 256 كيلو الذي تتم قراءة من خلال ملفوف ByteBuffer وكتب مباشرة من مجموعة البايت هي أسرع طريقة.

FileInputStream input = new FileInputStream("C:/logs.txt");
FileChannel channel = input.getChannel();
byte[] buffer = new byte[256 * 1024];
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);

try {
    for (int length = 0; (length = channel.read(byteBuffer)) != -1;) {
        System.out.write(buffer, 0, length);
        byteBuffer.clear();
    }
} finally {
    input.close();
}

نصائح أخرى

إذا كان كل ما تريد القيام به هو طباعة محتويات ملف (ولا تريد طباعة int/double/etc التالي.) إلى وحدة التحكم ثم أ BufferedReader على ما يرام.

الرمز الخاص بك لأنه لن ينتج النتيجة التي تتبعها ، رغم ذلك. جرب هذا بدلاً من ذلك:

BufferedReader in = new BufferedReader(new FileReader("C:\\logs\\log001.txt"));
String line = in.readLine();
while(line != null)
{
  System.out.println(line);
  line = in.readLine();
}
in.close();

لن أتعامل مع هذا الأمر ، على الرغم من أنه من المحتمل أن يكون عنق الزجاجة الرئيسي هو قدرة وحدة التحكم الخاصة بك على طباعة المعلومات التي ترسلها Java.

إذا كان كل ما تريده هو تفريغ محتويات الملف بكفاءة إلى وحدة التحكم مع عدم وجود معالجة بينهما بينهما ، فإن تحويل البيانات إلى أحرف وإيجاد فترات أسطر غير ضروري. بدلاً من ذلك ، يمكنك فقط قراءة كتل البايتات من الملف والكتابة ثم مباشرة إلى System.out:

package toconsole;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class Main {
    public static void main(String[] args) {
        BufferedInputStream bis = null;
        byte[] buffer = new byte[8192];
        int bytesRead = 0;
        try {
            bis = new BufferedInputStream(new FileInputStream(args[0]));
            while ((bytesRead = bis.read(buffer)) != -1) {
                System.out.write(buffer, /* start */ 0, /* length */ bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try { bis.close(); } catch (Exception e) { /* meh */ }
        }
    }
}

في حال لم تصادف هذا النوع من المصطلح من قبل ، فإن البيان في حالة الحين يعين كلا من نتيجة BIS.Read إلى BYTESREAD ثم يقارنها بـ -1. لذلك نستمر في قراءة البايتات في المخزن المؤقت حتى يتم إخبارنا بأننا في نهاية الملف. ونحن نستخدم bytesread في system.out.write للتأكد من أننا نكتب فقط البايتات التي نقرأها للتو ، حيث لا يمكننا افتراض أن جميع الملفات يبلغ طولها 8 كيلو بايت!

إذا كان ملفًا صغيرًا نسبيًا ، فإن طريقة Java 7+ ذات السطر الواحد للقيام بذلك هي:

System.out.println(new String(Files.readAllBytes(Paths.get("logs.txt"))));

نرى https://docs.oracle.com/javase/7/docs/api/java/nio/file/package-summary.html لمزيد من التفاصيل.

هتافات!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top