سؤال

أحتاج إلى أن أكون قادرًا على تقليد "الذيل -f" مع جافا. أحاول قراءة ملف السجل لأنه يتم كتابته بواسطة عملية أخرى ، لكن عندما أفتح الملف لقراءته ، فإنه يحبس الملف ولا يمكن للكتابة إليه بعد الآن. أي مساعدة سيكون موضع تقدير كبير!

إليك الرمز الذي أستخدمه حاليًا:

public void read(){
    Scanner fp = null;
    try{
        fp = new Scanner(new FileReader(this.filename));
        fp.useDelimiter("\n");
    }catch(java.io.FileNotFoundException e){
        System.out.println("java.io.FileNotFoundException e");
    }
    while(true){
        if(fp.hasNext()){
            this.parse(fp.next());
        }           
    }       
}
هل كانت مفيدة؟

المحلول

يعتبر إعادة بناء الذيل صعبًا بسبب بعض الحالات الخاصة مثل اقتطاع الملف وحذف (وسيطة). لفتح الملف دون قفل الاستخدام StandardOpenOption.READ مع واجهة برمجة تطبيقات ملف Java الجديد مثل:

try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) {
    InputStreamReader reader = new InputStreamReader(is, fileEncoding);
    BufferedReader lineReader = new BufferedReader(reader);
    // Process all lines.
    String line;
    while ((line = lineReader.readLine()) != null) {
        // Line content content is in variable line.
    }
}

لمحاولتي إنشاء ذيل في جافا انظر:

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

نصائح أخرى

انظر إلى واجهة برمجة تطبيقات Filechannel هنا. لقفل الملف يمكنك التحقق منه هنا

يمنحك java.io قفل ملف إلزامي ويمنحك java.nio قفل ملف استشاري

إذا كنت ترغب في قراءة أي ملف دون أي قفل يمكنك استخدامه أدناه

import java.nio.channels.FileChannel;
import java.nio.file.Paths;

إذا كنت تريد ذنب سطر ملف حسب السطر ، فاستخدم الكود أدناه لنفسه

public void tail(String logPath){
    String logStr = null;
    FileChannel fc = null;
    try {
        fc = FileChannel.open(Paths.get(logPath), StandardOpenOption.READ);
        fc.position(fc.size());
    } catch (FileNotFoundException e1) {
        System.out.println("FileNotFoundException occurred in Thread : " + Thread.currentThread().getName());
        return;
    } catch (IOException e) {
        System.out.println("IOException occurred while opening FileChannel in Thread : " + Thread.currentThread().getName());
    }
    while (true) {
        try {
            logStr = readLine(fc);
            if (logStr != null) {
                System.out.println(logStr);
            } else {
                Thread.sleep(1000);
            }
        } catch (IOException|InterruptedException e) {
            System.out.println("Exception occurred in Thread : " + Thread.currentThread().getName());
            try {
                fc.close();
            } catch (IOException e1) {
            }
            break;
        }
    }
}

private String readLine(FileChannel fc) throws IOException {
    ByteBuffer buffers = ByteBuffer.allocate(128);
    // Standard size of a line assumed to be 128 bytes
    long lastPos = fc.position();
    if (fc.read(buffers) > 0) {
        byte[] data = buffers.array();
        boolean foundTmpTerminator = false;
        boolean foundTerminator = false;
        long endPosition = 0;
        for (byte nextByte : data) {
            endPosition++;
            switch (nextByte) {
            case -1:
                foundTerminator = true;
                break;
            case (byte) '\r':
                foundTmpTerminator = true;
                break;
            case (byte) '\n':
                foundTmpTerminator = true;
                break;
            default:
                if (foundTmpTerminator) {
                    endPosition--;
                    foundTerminator = true;
                }
            }
            if (foundTerminator) {
                break;
            }
        }
        fc.position(lastPos + endPosition);
        if (foundTerminator) {
            return new String(data, 0, (int) endPosition);
        } else {
            return new String(data, 0, (int) endPosition) + readLine(fc);
        }
    }
    return null;
}

يستخدم Windows قفلًا إلزاميًا للملفات ما لم تحدد أعلام المشاركة المناسبة أثناء فتحك. إذا كنت ترغب في فتح ملف مزدحم ، فأنت بحاجة إلى win32-api CreateFile مقبض مع أعلام المشاركة FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE.

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

أعتقد أنه عمل سريع من حولك يمكنه القراءة process.getInputStream() من الأمر "cmd /D/C type file.lck"

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