简体   繁体   中英

How to read and write data into same file simultaneously

I have read many a posts where-in they speak about reading and writing into the file NOT simultaneously using JavaME. I have a special use case scenarios where-in my log file (maybe full file or just portion of the file) is uploaded to the server on regular basis. This must continue without hampering the current logging of the application in this same file.

The code sample is a under:

boolean writing = true;
boolean reading = true;
void main() {
    new Thread("THREAD-FILE-READ") {
        public void run() {
            InputStream instream = getFileInStream();
            if (null != instream) {
                while (reading) {
                    try {
                        try {
                            synchronized(READ_LOCK) {
                                READ_LOCK.wait();
                            }
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }

                        if (writtenCharsLen > 0) {
                            byte[] bytes = new byte[writtenCharsLen];
                            instream.read(bytes, 0, writtenCharsLen);
                            System.out.println("Read="+new String(bytes));
                            bytes = null;
                            writtenCharsLen = 0;
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            }
            closeStream(instream);
        }
    }.start();

    new Thread("THREAD-FILE-WRITE") {
        public void run() {
            OutputStream outstream = getFileOutStream();
            if (null != outstream) {
                while (writing) {
                    try {
                        byte[] str = randomString();
                        if (null != str) {
                            writtenCharsLen = str.length;
                            System.out.println("Write=" + new String(str));
                            outstream.write(str);
                            str = null;
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();

                    } finally {
                        notifyReadStream();
                    }

                    try {
                        synchronized(WRITE_LOCK) {
                            WRITE_LOCK.wait();
                        }
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
            closeStream(outstream );
        }
    }.start();

}

void notifyReadStream() {
    try {
        synchronized (READ_LOCK) {
            READ_LOCK.notify();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

void notifyWriteStream() {
    try {
        synchronized (WRITE_LOCK) {
            WRITE_LOCK.notify();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

In the above code I will replace sop-read and sop-write with proper calls to network IO methods.

PS: Since this piece of code will run of multiple files and multitude of devices i need the modification as compressed as possible to keep my runtime heap as low as possible. Also this piece of code will run till the application life cycle hence closing and opening the file in middle is out of consideration.

Present Undesired Result: The read and write threads are showing running sop's for read and write. The read thread is reading from the position the writing thread has written. I am not facing any exception in this code but the result is undesired. I have also tried synchronizing read and write streams but that is throwing IllegalMonitorStateException

Expected Result: Reading of the stream must be triggered after writing into the stream is completed, also the read thread must be able to read from any position in the file.

Any help / pointers is useful?

EDIT: I was able to synchronize the read and the write streams using different monitors but i still feel, i could have done better using single monitor. Will try it sometime later.

I will attack this problem:

Present Undesired Result : The read and write threads are showing running sop's for read and write. The read thread is reading from the position the writing thread has written. I am not facing any exception in this code but the result is undesired. I have also tried synchronizing read and write streams but that is throwing IllegalMonitorStateException .

If you have synchronized the access using monitors ie the reader calls someObject.wait() and the writer calls someObject.notify() , remember that you have to wrap these calls in a synchronized block on someObject :

synchronized(someObject) {
    someObject.wait();
}


synchronized(someObject) {
    someObject.notify();
}

This is the cause for IllegalMonitorStateException .

Your first problem is that you are setting writtenCharsLen before you write the data. If your read thread sees it being non-zero before the write thread actually writes it, you have a problem. Move writtenCharsLen = str.length after the write.

Another problem I see in your sample is that the threads never yield control. They will be CPU hogs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM