सक्रिय रूप से लिखी जा रही फ़ाइल से पढ़ने के लिए मैं जावा का उपयोग कैसे करूं?

मेरे पास एक ऐसा एप्लिकेशन है जो फ़ाइल को जानकारी लिखता है। आवेदन की पास / विफलता / शुद्धता निर्धारित करने के लिए इस जानकारी का उपयोग निष्पादन के बाद किया जाता है। मैं फ़ाइल को पढ़ने के लिए सक्षम होना चाहता हूं क्योंकि यह लिखा जा रहा है ताकि मैं वास्तविक समय में इन पास / विफलता / शुद्धता जांच कर सकूं।

मुझे लगता है कि ऐसा करना संभव है, लेकिन जावा का उपयोग करते समय गॉचा का क्या शामिल है? अगर पठन लेखन तक पहुंच जाता है, तो क्या यह फ़ाइल बंद होने तक और अधिक लिखने की प्रतीक्षा करेगा, या पढ़ा जाएगा इस बिंदु पर एक अपवाद फेंक देगा? यदि उत्तरार्द्ध, तो मैं क्या करूँ?

मेरा अंतर्ज्ञान वर्तमान में मुझे बुफर्डस्ट्रीम की तरफ धक्का दे रहा है। क्या यह जाने का रास्ता है?

0
ro fr bn
@EJP - आप किस डीबी की सिफारिश करते हैं? मुझे लगता है कि MySQL एक अच्छी शुरुआत है?
जोड़ा लेखक Coffee, स्रोत
डेटाबेस का प्रयोग करें। ये 'एक फाइल पढ़ते हैं जबकि इसे लिखा जा रहा है' आँसू आँसू में खत्म होते हैं।
जोड़ा लेखक EJP, स्रोत
अरे, जैसा कि मुझे एक समान परिदृश्य का सामना करना पड़ रहा है, अगर आप स्वीकार किए गए एक से बेहतर समाधान प्राप्त कर चुके हैं तो मैं शब्द कर रहा था?
जोड़ा लेखक Asaf David, स्रोत
मुझे पता है कि यह एक पुराना सवाल है, लेकिन भविष्य के पाठकों के लिए, क्या आप अपने उपयोग के मामले में थोड़ा और विस्तार कर सकते हैं? अधिक जानकारी के बिना, एक आश्चर्य अगर आप शायद गलत समस्या को हल कर रहे हैं।
जोड़ा लेखक user359996, स्रोत

10 उत्तर

मैंने कभी कोशिश नहीं की है, लेकिन आपको यह देखने के लिए एक टेस्ट केस लिखना चाहिए कि अंत में हिट करने के बाद स्ट्रीम से पढ़ना काम करेगा, भले ही फ़ाइल में अधिक डेटा लिखा गया हो।

क्या कोई कारण है कि आप एक पाइप इनपुट / आउटपुट स्ट्रीम का उपयोग नहीं कर सकते हैं? क्या डेटा एक ही एप्लिकेशन से लिखा और पढ़ा जा रहा है (यदि हां, तो आपके पास डेटा है, आपको फ़ाइल से पढ़ने की आवश्यकता क्यों है)?

अन्यथा, शायद फ़ाइल के अंत तक पढ़ा जाए, फिर परिवर्तनों की निगरानी करें और जहां आपने छोड़ा और जारी रखा, वहां खोजें ... हालांकि दौड़ की स्थिति के लिए देखें।

0
जोड़ा

जावा प्रति-से नहीं, लेकिन आप उन मुद्दों पर जा सकते हैं जहां आपने फ़ाइल में कुछ लिखा है, लेकिन यह वास्तव में अभी तक लिखा नहीं गया है - यह कहीं कैश में हो सकता है, और उसी फ़ाइल से पढ़ने से आपको वास्तव में नहीं मिल सकता है नई जानकारी।

लघु संस्करण - फ़्लश() का उपयोग करें या जो भी प्रासंगिक सिस्टम कॉल यह सुनिश्चित करने के लिए है कि आपका डेटा वास्तव में फ़ाइल में लिखा गया हो।

नोट: मैं ओएस स्तर डिस्क कैश के बारे में बात नहीं कर रहा हूं - यदि आपका डेटा यहां आता है, तो इस बिंदु के बाद इसे पढ़ने() में दिखाई देना चाहिए। यह हो सकता है कि भाषा स्वयं ही कैश लिखती है, बफर भरने तक प्रतीक्षा या फ़ाइल फ्लश / बंद हो जाती है।

0
जोड़ा

जवाब "नहीं" ... और "हां" लगता है। यह जानने का कोई वास्तविक तरीका नहीं है कि फ़ाइल किसी अन्य एप्लिकेशन द्वारा लिखित के लिए खुली है या नहीं। इसलिए, ऐसी फ़ाइल से पढ़ना तब तक प्रगति करेगा जब तक सामग्री समाप्त न हो जाए। मैंने माइक की सलाह ली और कुछ टेस्ट कोड लिखा:

Writer.java फ़ाइल करने के लिए एक स्ट्रिंग लिखता है और फिर फ़ाइल के लिए एक और पंक्ति लिखने से पहले उपयोगकर्ता को प्रवेश करने की प्रतीक्षा करता है। विचार यह है कि इसे शुरू किया जा सकता है, फिर एक पाठक को यह देखने के लिए शुरू किया जा सकता है कि यह "आंशिक" फ़ाइल के साथ कैसे copes। मैंने जो पाठक लिखा है वह रीडर.जावा में है।

Writer.java

public class Writer extends Object
{
    Writer() {

    }

    public static String[] strings = 
        {
            "Hello World", 
            "Goodbye World"
        };

    public static void main(String[] args) 
        throws java.io.IOException {

        java.io.PrintWriter pw =
            new java.io.PrintWriter(new java.io.FileOutputStream("out.txt"), true);

        for(String s : strings) {
            pw.println(s);
            System.in.read();
        }

        pw.close();
    }
}

Reader.java

public class Reader extends Object
{
    Reader() {

    }

    public static void main(String[] args) 
        throws Exception {

        java.io.FileInputStream in = new java.io.FileInputStream("out.txt");

        java.nio.channels.FileChannel fc = in.getChannel();
        java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(10);

        while(fc.read(bb) >= 0) {
            bb.flip();
            while(bb.hasRemaining()) {
                System.out.println((char)bb.get());
            }
            bb.clear();
        }

        System.exit(0);
    }
}

कोई गारंटी नहीं है कि यह कोड सर्वोत्तम अभ्यास है।

यह समय-समय पर माइक द्वारा सुझाए गए विकल्प को छोड़ देता है कि फाइल से नया डेटा पढ़ा जा रहा है या नहीं। इसके बाद फ़ाइल रीडर को बंद करने के लिए उपयोगकर्ता हस्तक्षेप की आवश्यकता होती है जब यह निर्धारित किया जाता है कि पढ़ना पूरा हो गया है। या, पाठक को फ़ाइल की सामग्री से अवगत कराया जाना चाहिए और लिखने की स्थिति निर्धारित करने और समाप्त करने में सक्षम होना चाहिए। यदि सामग्री एक्सएमएल थी, तो दस्तावेज का अंत इसका संकेत देने के लिए इस्तेमाल किया जा सकता था।

0
जोड़ा

आप फ़ाइल के एक हिस्से को लॉक करने के लिए जावा चैनल को भी देख सकते हैं।

http://java.sun.com/javase /6/docs/api/java/nio/channels/FileChannel.html

FileChannel का यह कार्य प्रारंभ हो सकता है

lock(long position, long size, boolean shared) 

इस विधि का एक आमंत्रण तब तक अवरुद्ध होगा जब तक कि क्षेत्र को लॉक नहीं किया जा सके

0
जोड़ा

टेलर । यह किनारे के अधिकांश मामलों को संभालता है।

0
जोड़ा

मैं पूरी तरह से यहोशू की प्रतिक्रिया से सहमत हूं, टेलर इस स्थिति में नौकरी के लिए उपयुक्त है। यहाँ एक उदाहरण है :

यह प्रत्येक 150 एमएस फ़ाइल में एक पंक्ति लिखता है, जबकि हर 2500 एमएस में यह वही फाइल पढ़ता है

public class TailerTest
{
    public static void main(String[] args)
    {
        File f = new File("/tmp/test.txt");
        MyListener listener = new MyListener();
        Tailer.create(f, listener, 2500);

        try
        {
            FileOutputStream fos = new FileOutputStream(f);
            int i = 0;
            while (i < 200)
            {
                fos.write(("test" + ++i + "\n").getBytes());
                Thread.sleep(150);
            }
            fos.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private static class MyListener extends TailerListenerAdapter
    {
        @Override
        public void handle(String line)
        {
            System.out.println(line);
        }
    }
}
0
जोड़ा
टेलर के लिए आपका लिंक टूटा हुआ है।
जोड़ा लेखक Stealth Rabbi, स्रोत
@StealthRabbi करने के लिए सबसे अच्छी बात यह है कि सही लिंक की तलाश करें और इसके साथ जवाब संपादित करें।
जोड़ा लेखक igracia, स्रोत

आप FileInputStream, FileReader या RandomAccessFile का उपयोग कर किसी अन्य प्रक्रिया से खोले गए फ़ाइल को नहीं पढ़ सकते हैं।

लेकिन FileChannel का उपयोग सीधे काम करेगा:

private static byte[] readSharedFile(File file) throws IOException {
    byte buffer[] = new byte[(int) file.length()];
    final FileChannel fc = FileChannel.open(file.toPath(), EnumSet.of(StandardOpenOption.READ));
    final ByteBuffer dst = ByteBuffer.wrap(buffer);
    fc.read(dst);
    fc.close();
    return buffer;
}
0
जोड़ा

FileChannel.read (बाइटबफर) का उपयोग करके काम करने के लिए उदाहरण नहीं मिला क्योंकि यह अवरुद्ध पढ़ने वाला नहीं है। हालांकि काम करने के लिए नीचे दिए गए कोड को मिला:

boolean running = true;
BufferedInputStream reader = new BufferedInputStream(new FileInputStream( "out.txt" ) );

public void run() {
    while( running ) {
        if( reader.available() > 0 ) {
            System.out.print( (char)reader.read() );
        }
        else {
            try {
                sleep( 500 );
            }
            catch( InterruptedException ex ) {
                running = false;
            }
        }
    }
}

बेशक एक ही चीज़ धागे की बजाय टाइमर के रूप में काम करेगी, लेकिन मैं इसे प्रोग्रामर तक छोड़ देता हूं। मैं अभी भी एक बेहतर तरीका ढूंढ रहा हूं, लेकिन यह मेरे लिए अभी काम करता है।

ओह, और मैं इसे इसके साथ चेतावनी दूंगा: मैं 1.4.2 का उपयोग कर रहा हूं। हाँ मुझे पता है कि मैं पत्थर युग में अभी भी हूं।

0
जोड़ा
इसे जोड़ने के लिए धन्यवाद ... कुछ ऐसा करने के लिए मैं कभी नहीं मिला। मुझे लगता है कि फाइल को लॉक करने का ब्लेड का जवाब भी एक अच्छा है। हालांकि, इसे जावा 6 (मुझे लगता है) की आवश्यकता है।
जोड़ा लेखक Anthony Cramp, स्रोत
@ एंथनीक्रैम्प आप बक्षीस क्यों नहीं दे रहे हैं? :)
जोड़ा लेखक Yassin Hajaj, स्रोत
@ जोसेफ गॉर्डन - आपको इन दिनों में से किसी एक ड्रोन युग में जाना होगा ;-)
जोड़ा लेखक TungstenX, स्रोत

एक ओपन सोर्स जावा ग्राफिक टेल है जो यह करता है।

https://stackoverflow.com/a/559146/1255493

public void run() {
    try {
        while (_running) {
            Thread.sleep(_updateInterval);
            long len = _file.length();
            if (len < _filePointer) {
                // Log must have been jibbled or deleted.
                this.appendMessage("Log file was reset. Restarting logging from start of file.");
                _filePointer = len;
            }
            else if (len > _filePointer) {
                // File must have had something added to it!
                RandomAccessFile raf = new RandomAccessFile(_file, "r");
                raf.seek(_filePointer);
                String line = null;
                while ((line = raf.readLine()) != null) {
                    this.appendLine(line);
                }
                _filePointer = raf.getFilePointer();
                raf.close();
            }
        }
    }
    catch (Exception e) {
        this.appendMessage("Fatal error reading log file, log tailing has stopped.");
    }
    // dispose();
}
0
जोड़ा

यदि आप लिखे जाने पर फ़ाइल को पढ़ना चाहते हैं और केवल नई सामग्री को पढ़ना चाहते हैं तो निम्नलिखित आपको इसे प्राप्त करने में मदद करेगा।

इस प्रोग्राम को चलाने के लिए आप इसे कमांड प्रॉम्प्ट / टर्मिनल विंडो से लॉन्च करेंगे और फ़ाइल नाम को पढ़ने के लिए पास करेंगे। जब तक आप प्रोग्राम को मार नहीं देते तब तक यह फ़ाइल को पढ़ेगा।

जावा फ़ाइल रीडर सी: \ myfile.txt

जैसा कि आप पाठ की एक पंक्ति टाइप करते हैं, इसे नोटपैड से सहेजते हैं और आपको कंसोल में मुद्रित पाठ दिखाई देगा।

public class FileReader {

    public static void main(String args[]) throws Exception {
        if(args.length>0){
            File file = new File(args[0]);
            System.out.println(file.getAbsolutePath());
            if(file.exists() && file.canRead()){
                long fileLength = file.length();
                readFile(file,0L);
                while(true){

                    if(fileLength
0
जोड़ा
यह कोड बहुत सारे CPU का उपभोग करता है क्योंकि लूप में थ्रेड नहीं होता है। इसमें कॉल करें। थोड़ी सी देरी जोड़ने के बिना यह कोड सीपीयू को बहुत व्यस्त रखने में रहता है।
जोड़ा लेखक ChaitanyaBhatt, स्रोत
क्या संभावना नहीं है कि, फ़ाइल के समय के बीच और फ़ाइल की लंबाई के समय के बीच, बाहरी प्रक्रिया फ़ाइल में अधिक डेटा जोड़ सकती है। यदि ऐसा है, तो परिणामस्वरूप फ़ाइल में लिखे गए डेटा को पढ़ने की प्रक्रिया गायब हो जाएगी।
जोड़ा लेखक JohnC, स्रोत