Как читать и записывать данные в один файл одновременно - PullRequest
3 голосов
/ 13 декабря 2011

Я прочитал много постов, в которых говорится о чтении и записи в файл НЕ одновременно с использованием JavaME.У меня есть особые сценарии использования, когда мой файл журнала (может быть, полный файл или просто часть файла) регулярно загружается на сервер.Это должно продолжаться, не мешая текущей регистрации приложения в этом же файле.

Пример кода ниже:

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

В приведенном выше коде я заменю sop-read и sop-пишите с правильными вызовами к сетевым методам ввода-вывода.

PS: Так как этот фрагмент кода будет работать с несколькими файлами и множеством устройств, мне нужно как можно более сжатое изменение, чтобы моя куча времени выполнения была как можно меньше.Также этот фрагмент кода будет работать до жизненного цикла приложения, поэтому закрытие и открытие файла посередине не рассматривается.

Текущий нежелательный результат: Потоки чтения и записи показывают запущенные sopдля чтения и записи.Поток чтения читает с позиции, которую написал поток записи.Я не сталкиваюсь ни с каким исключением в этом коде, но результат нежелателен.Я также пытался синхронизировать потоки чтения и записи, но это вызывает IllegalMonitorStateException

Ожидаемый результат: Чтение потока должно быть запущено после завершения записи в поток, также поток чтениядолжен быть в состоянии читать из любой позиции в файле.

Любая помощь / указатели полезны?

РЕДАКТИРОВАТЬ: Мне удалось синхронизировать потоки чтения и записииспользуя разные мониторы, но я все еще чувствую, я мог бы сделать лучше, используя один монитор.Попробую это позже.

Ответы [ 2 ]

1 голос
/ 13 декабря 2011

Я буду атаковать эту проблему:

Текущий нежелательный результат : Потоки чтения и записи показывают запущенные sop для чтения и записи.Поток чтения читает с позиции, которую написал поток записи.Я не сталкиваюсь ни с каким исключением в этом коде, но результат нежелателен.Я также пытался синхронизировать потоки чтения и записи, но это выдает IllegalMonitorStateException.

Если вы синхронизировали доступ с помощью мониторов, т.е. читатель вызывает someObject.wait(), а писатель вызывает someObject.notify(), помните, что у вас естьобернуть эти вызовы в синхронизированный блок на someObject:

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


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

Это причина для IllegalMonitorStateException.

0 голосов
/ 13 декабря 2011

Ваша первая проблема заключается в том, что вы устанавливаете значение параметраchedCharsLen до записи данных. Если ваш поток чтения видит, что он ненулевой, прежде чем поток записи действительно его записывает, у вас есть проблема. Переместить записанныйCharsLen = str.length после записи.

Другая проблема, которую я вижу в вашем примере, состоит в том, что потоки никогда не дают контроль. Это будут процессоры.

...