সক্রিয়ভাবে লেখা হচ্ছে এমন কোনও ফাইল থেকে পড়তে আমি কীভাবে জাভা ব্যবহার করব?


99

আমার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা ফাইল করার জন্য তথ্য লেখায়। এই তথ্যটি প্রয়োগের পাস / ব্যর্থতা / যথার্থতা নির্ধারণের জন্য মৃত্যুদণ্ড কার্যকর করার পরে ব্যবহৃত হয়। আমি ফাইলটি যেমন লেখা হচ্ছে তা পড়তে সক্ষম হতে চাই যাতে আমি এই পাস / ব্যর্থতা / যথার্থতা পরীক্ষা করতে পারি রিয়েল টাইমে।

আমি ধরে নিলাম এটি করা সম্ভব, তবে জাভা ব্যবহার করার সময় গটচা জড়িত কী? পড়া যদি লেখার দিকেই ধরে, ফাইলটি বন্ধ না হওয়া পর্যন্ত এটি কি আরও লেখার অপেক্ষা রাখে, বা পাঠক এই মুহুর্তে একটি ব্যতিক্রম ছুঁড়ে ফেলবে? যদি পরেরটি হয় তবে আমি কী করব?

আমার স্বজ্ঞাততা বর্তমানে আমাকে বাফার্ড স্ট্রিমের দিকে চাপ দিচ্ছে। এই কি এই পথ?


4
আরে, আমি যখন একইরকম দৃশ্যের মুখোমুখি হচ্ছিলাম তখন আমি কথা বলছিলাম যদি আপনি গ্রহণযোগ্যটির চেয়ে আরও ভাল সমাধান খুঁজে পান?
আসফ ডেভিড

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে ভবিষ্যতের পাঠকদের জন্য আপনি কি আপনার ব্যবহারের ক্ষেত্রে আরও কিছুটা প্রসারিত করতে পারেন? আরও তথ্য না থাকলে, আপনি সম্ভবত ভুল সমস্যাটি সমাধান করছেন কিনা তা অবাক করে।
ব্যবহারকারী 359996

অ্যাপাচি কমন্স আইও থেকে টেলরটি ব্যবহার করে দেখুন । এটি বেশিরভাগ প্রান্তের কেসগুলি পরিচালনা করে।
জোশুয়া

4
একটি ডাটাবেস ব্যবহার করুন। এগুলি 'কোনও ফাইলের লেখা থাকাকালীন পড়তে থাকে' দৃশ্যগুলি কান্নায় শেষ হয়।
লার্নের মারকুইস

@ এজেপি - আপনি কোন ডিবি সুপারিশ করবেন? আমি অনুমান করছি মাইএসকিউএল একটি ভাল শুরু?
কফি

উত্তর:


39

ব্যবহার করে কাজ করার উদাহরণটি FileChannel.read(ByteBuffer)পাওয়া যায়নি কারণ এটি কোনও ব্লক পড়া নয়। তবে কাজের জন্য নীচের কোডটি পেয়েছেন:

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;
            }
        }
    }
}

অবশ্যই একই জিনিসটি থ্রেডের পরিবর্তে টাইমার হিসাবে কাজ করবে, তবে আমি এটি প্রোগ্রামারটির উপরে রেখে দিই। আমি এখনও আরও ভাল উপায় খুঁজছি, তবে এটি আপাতত আমার জন্য কাজ করে।

ওহ, এবং আমি এটি দিয়ে সাবধান করব: আমি ১.৪.২ ব্যবহার করছি। হ্যাঁ আমি জানি আমি এখনও প্রস্তর যুগে আছি।


4
এটি যুক্ত করার জন্য ধন্যবাদ ... এমন কিছু যা আমি কখনই করতে পারি নি। আমি মনে করি ফাইলটি লক করার জন্য ব্লেডের উত্তরটিও ভাল। তবে এর জন্য জাভা 6 দরকার (আমার মনে হয়)।
অ্যান্টনি ক্র্যাম্প

@JosephGordon - তুমি ড্রোন বয়সের এই দিনের কথা বলে ;-) এক সরাতে হবে
TungstenX

12

আপনি যদি কোনও ফাইল লেখার সময় পড়তে চান এবং কেবলমাত্র নতুন সামগ্রীটি পড়তে চান তবে নিম্নলিখিতগুলি আপনাকে সেটি অর্জনে সহায়তা করবে।

এই প্রোগ্রামটি চালাতে আপনি এটি কমান্ড প্রম্পট / টার্মিনাল উইন্ডো থেকে চালু করবেন এবং ফাইলটির নামটি পড়তে পারবেন। আপনি প্রোগ্রামটি না মেরে এটি ফাইলটি পড়বে।

java FileReader c: \ 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<file.length()){
                        readFile(file,fileLength);
                        fileLength=file.length();
                    }
                }
            }
        }else{
            System.out.println("no file to read");
        }
    }

    public static void readFile(File file,Long fileLength) throws IOException {
        String line = null;

        BufferedReader in = new BufferedReader(new java.io.FileReader(file));
        in.skip(fileLength);
        while((line = in.readLine()) != null)
        {
            System.out.println(line);
        }
        in.close();
    }
}

4
ফাইলটি পড়ার সময় এবং ফাইলের দৈর্ঘ্য গ্রহণের সময়কালের মধ্যে বাহ্যিক প্রক্রিয়া ফাইলটিতে আরও ডেটা যুক্ত করতে পারে এমন সম্ভাবনা কি নেই? যদি তা হয় তবে এর ফলে ফাইলটিতে লিখিত তথ্য পড়ার প্রক্রিয়াটি হারিয়ে যাবে।
জনসি

4
এই কোডটিতে প্রচুর সিপিইউ খরচ হয় কারণ লুপটিতে থ্রেড নেই it অল্প পরিমাণে দেরি না করে এই কোডটি সিপিইউকে খুব ব্যস্ত রাখে।
ChaitanyaBhatt

উপরের উভয় মন্তব্যই সত্য এবং অতিরিক্ত BufferedReaderপ্রতিটি লুপ কলটিতে এই সৃষ্টিটি এত অর্থহীন। এটিকে তৈরি করার সাথে সাথে এড়িয়ে যাওয়া এখন প্রয়োজনীয় হবে না, কারণ বাফার পাঠকরা তাদের আগমনের সাথে সাথে নতুন লাইনগুলি পড়তেন।
পাইওটার

5

কোনও ফাইলের অংশ লক করার জন্য আপনি জাভা চ্যানেলটি একবার দেখে নিতে পারেন।

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

শক্তির এই ফাংশনটি FileChannelএকটি শুরু হতে পারে

lock(long position, long size, boolean shared) 

অঞ্চলটি লক না হওয়া পর্যন্ত এই পদ্ধতির একটি অনুরোধ অবরুদ্ধ থাকবে


5

আমি জোশুয়ার প্রতিক্রিয়া , টেইলারের সাথে পুরোপুরি একমত এই পরিস্থিতিতে কাজের জন্য উপযুক্ত। এখানে একটি উদাহরণ:

প্রতি 2500 এমএসে খুব একই ফাইলটি পড়ার সময় এটি একটি ফাইলে প্রতি 150 এমএসে একটি লাইন লিখে রাখে

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);
        }
    }
}

টেলারের সাথে আপনার লিঙ্কটি নষ্ট হয়ে গেছে।
স্টিলথ রাব্বি

4
@ স্টেথাল্যাব্বি তারপরে সবচেয়ে ভাল কাজটি হ'ল সঠিক লিঙ্কটি অনুসন্ধান করা এবং এর সাথে উত্তরটি সম্পাদনা করা।
igracia

3

উত্তরটি "না" ... এবং "হ্যাঁ" বলে মনে হচ্ছে। অন্য কোনও অ্যাপ্লিকেশন দ্বারা কোনও ফাইল লেখার জন্য খোলা আছে কিনা তা জানার কোনও আসল উপায় নেই বলে মনে হয়। সুতরাং, বিষয়বস্তু নিঃশেষ না হওয়া পর্যন্ত এই জাতীয় ফাইল থেকে পড়া কেবল অগ্রগতি করবে। আমি মাইকের পরামর্শ নিয়ে কিছু পরীক্ষার কোড লিখেছিলাম:

Writer.java ফাইলের জন্য একটি স্ট্রিং লিখে তারপরে ফাইলটি অন্য একটি লাইন লেখার আগে ব্যবহারকারীর প্রবেশের জন্য অপেক্ষা করে। ধারণাটি এই যে এটি শুরু করা যেতে পারে, তবে একটি পাঠক এটি "আংশিক" ফাইলটি কীভাবে কপি করে তা দেখতে শুরু করা যেতে পারে। আমি যে পাঠকটি লিখেছি তা রিডার.জভাতে রয়েছে।

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();
    }
}

পাঠক.জভা

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);
    }
}

এই কোডটি সর্বোত্তম অনুশীলনের কোনও গ্যারান্টি নেই।

এটি ফাইল থেকে নতুন ডেটা পড়ার দরকার আছে কিনা তা পর্যায়ক্রমিকভাবে পরীক্ষা করার জন্য মাইকের প্রস্তাবিত বিকল্পটি ছেড়ে যায়। এরপরে পাঠকটি সম্পূর্ণরূপে নির্ধারিত হয়ে গেলে ফাইল রিডারটি বন্ধ করতে ব্যবহারকারীর হস্তক্ষেপের প্রয়োজন requires অথবা, পাঠককে ফাইলের বিষয়বস্তু সম্পর্কে সচেতন করা প্রয়োজন এবং লেখার শর্তটি নির্ধারণ এবং শেষ করতে সক্ষম হতে হবে। বিষয়বস্তুটি যদি এক্সএমএল হয়, তবে ডকুমেন্টের শেষটি এটি ব্যবহার করতে পারে to


1

প্রতি জাভা জাভা নয়, তবে আপনি এমন কোনও সমস্যার সমাধান করতে পারেন যেখানে আপনি কোনও ফাইলে কিছু লিখেছেন, তবে এটি এখনও লেখা হয়নি - এটি কোথাও কোনও ক্যাশে থাকতে পারে, এবং একই ফাইলটি থেকে পড়া আপনাকে সম্ভবত দিতে না পারে নতুন তথ্য।

সংক্ষিপ্ত সংস্করণ - আপনার ডেটা আসলে ফাইলটিতে লিখিত আছে তা নিশ্চিত করতে ফ্লাশ () বা প্রাসঙ্গিক সিস্টেম কল যাই হোক না কেন ব্যবহার করুন।

দ্রষ্টব্য আমি ওএস স্তরের ডিস্ক ক্যাশে নিয়ে কথা বলছি না - যদি আপনার ডেটা এখানে প্রবেশ করে তবে এটি এই পয়েন্টের পরে একটি পঠিত () এ উপস্থিত হওয়া উচিত। এটি এমনও হতে পারে যে ভাষাটি নিজেরাই লিখিত করে, কোনও বাফার পূরণ না হওয়া বা ফাইলটি ফ্লাশ / বন্ধ না হওয়া পর্যন্ত অপেক্ষা করে।


1

একটি মুক্ত উত্স জাভা গ্রাফিক টেইল রয়েছে যা এটি করে।

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();
}

1

আপনি এমন ফাইল পড়তে পারবেন না যা ফাইলআইপুটস্ট্রিম, ফাইলরেডার বা র্যান্ডমএকসেসফাইল ব্যবহার করে অন্য প্রক্রিয়া থেকে খোলা থাকে।

তবে সরাসরি ফাইলচ্যানেল ব্যবহার করা কাজ করবে:

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

আমি এটি কখনও চেষ্টা করে দেখিনি, তবে ফাইলটি আরও ডেটা লিখিত আছে কিনা তা নির্বিশেষে আপনার শেষের দিকে যাওয়ার পরে কোনও স্ট্রিম থেকে পড়া কাজ করবে কিনা তা পরীক্ষা করার জন্য আপনার পরীক্ষা করা উচিত।

আপনি পাইপযুক্ত ইনপুট / আউটপুট স্ট্রিমটি ব্যবহার করতে পারবেন না এমন কোনও কারণ আছে? একই অ্যাপ্লিকেশন থেকে ডেটা কি লিখিত এবং পঠিত হচ্ছে (যদি তাই হয়, আপনার কাছে ডেটা আছে, আপনার ফাইলটি পড়তে হবে কেন)?

অন্যথায়, সম্ভবত ফাইলের শেষ অবধি পড়ুন, তারপরে পরিবর্তনগুলি পর্যবেক্ষণ করুন এবং আপনি কোথায় রেখে গিয়েছেন এবং চালিয়ে যান তা সন্ধান করুন ... যদিও বর্ণের শর্তগুলি লক্ষ্য রাখুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.