Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > беда сRandomAccessFile.writeInt


Автор: _hunter 16.8.2012, 21:39
Добрый вечер,

Помогите со странной проблемой: пишу в pipe с помощью RandomAccessFile.writeInt:
RandomAccessFile pipe = new RandomAccessFile("\\\\.\\pipe\\rmserverpipe", "rws");
pipe.writeInt(0xABCDEF12);
запись проходит "нормально" -- exception не бросается. Но "на другом конце" (читаю в "плюсах") из pipe'а вычитывается только один байт. Повторная "вычитка" дочитывает остальные три байта...

На чтении все банально:
result = ::ReadFile(pipe, &data, 4, &bytesRead, NULL);
и при "плюсовой" записи все вычитывается за один раз.

Соответственно вопрос: как "это" бороть?

С уважением...

Автор: leniviy 16.8.2012, 22:00
Я считаю, это норма. Даже если удастся побороть в данном случае, всё равно будет ненадежно. Так что надо ReadFile вызывать в цикле. И вообще инты надо передавать в network byte order.

Код

  u_long ul;
  int i;
  char *pdata = (char*)&ul;
  DWORD bytesRead, left = sizeof(u_long);
  while(left) {
    ReadFile(pipe, pdata, left, &bytesRead, NULL);
    /* проверка ошибки */
    left -= bytesRead;
    pdata+= bytesRead;
  }
  i = ntohl(ul);

Автор: _hunter 16.8.2012, 22:08
Как это "норма"? -- Справка:
http://docs.oracle.com/javase/1.4.2/docs/api/java/io/RandomAccessFile.html#writeInt(int)
, вроде как, говорит что писаться должно четыре байта. Причем, почему-то, нет никаких механизмов контроля записи...

"Принимающее" приложение переписывать -- не вариант: оно уже работает и лезть туда никто не даст...

Автор: leniviy 16.8.2012, 22:17
Цитата(_hunter @  16.8.2012,  22:08 Найти цитируемый пост)
Вроде как, говорит что писаться должно четыре байта

Могу сделать предположение: жаба конвертит int в байт массив из 4 байт, меняет байты местами, и по-одному пишет в поток.
Винда успевает отправить первый байт, в это время буфер пайпа заполняется 3 оставшимися байтами.

Цитата(_hunter @  16.8.2012,  22:08 Найти цитируемый пост)
Причем, почему-то, нет никаких механизмов контроля записи...

Есть: IOException.

Цитата(_hunter @  16.8.2012,  22:08 Найти цитируемый пост)
оно уже работает и лезть туда никто не даст... 

баг в приложении.

Добавлено через 5 минут и 40 секунд
Во:
Код

    public final void writeInt(int v) throws IOException {
    write((v >>> 24) & 0xFF);
    write((v >>> 16) & 0xFF);
    write((v >>>  8) & 0xFF);
    write((v >>>  0) & 0xFF);
    //written += 4;
    }


Добавлено через 9 минут и 30 секунд
Попробуй так, но это из разряда ненадежных
Код

        byte[] bytes = { (byte)0xAB, (byte)0xCD, (byte)0xEF, (byte)0x12 };
        pipe.write(bytes);


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)