Поведение чтения FileChannel [дубликат]

Подумайте об этом так: он всегда проходит по значению. Однако значение объекта не является самим объектом, а ссылкой на этот объект.

Вот пример, передающий число (примитивный тип)

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
}
var x = 10;
changePrimitive(x);
// x === 10

Повторение этого с объектом дает разные результаты:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
}
var x = { val: 10 };
changeObject(x);
// x === { val: 100 }

One еще пример:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
}
var x = { val: 10 };
changeObject(x);
// x === { val: 10}
1
задан dogbane 19 October 2010 в 10:58
поделиться

2 ответа

Можно ли предположить, что метод возвращает число меньше предела данного буфера только тогда, когда в файле недостаточно байтов?

Javadoc говорит:

чтение может не заполнить буфер

и дает некоторые примеры, а

возвращает количество прочитанных байтов, возможно, ноль или -1, если канал достигнет конца потока.

Это НЕ ДОЛЖНО, чтобы позволить вам сделать это предположение.

На практике, вы, вероятно, всегда будете получать полный буфер при чтении из файла по модулю конца сценария файла. И это имеет смысл с точки зрения реализации ОС, учитывая накладные расходы на создание системного вызова.

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

Другая проблема заключается в том, что - некоторые типы потоков, где вы определенно получают частично заполненные буферы. Очевидными примерами являются потоки сокетов, трубы и консольные потоки. Если вы кодируете приложение, предполагающее поведение файлового потока, вы можете получить неприятное удивление, когда кто-то запускает его против другого типа потока ... и терпит неудачу.

3
ответ дан Stephen C 23 August 2018 в 02:22
поделиться
  • 1
    Javadocs do указывают, что нет гарантии, что количество запрошенных байтов будет считано. – Grodriguez 19 October 2010 в 12:12
  • 2
    @Grodriguez ... вот что я сказал. – Stephen C 19 October 2010 в 13:08
  • 3
    Вы сказали: «В javadoc не указано, что произойдет, кроме того, что вы получите только нулевые символы, если вы находитесь в конце файла (или эквивалента). & Quot; Но Javadoc действительно указывает гораздо больше. В нем явно указано, что вы не можете считать, что запрошенное количество байтов будет считано, и что единственная гарантия заключается в том, что в режиме блокировки будет считаться хотя бы один байт. – Grodriguez 19 October 2010 в 13:19
  • 4
    @Grodriguez - ", вы не можете предположить, что запрошенное количество байтов будет считано & quot; является NOT спецификацией того, что произойдет. Скорее, это утверждение, что что-то неуказано . Когда я сказал, что "не указывает, что произойдет" , я очень тщательно выбрал слова. – Stephen C 19 October 2010 в 15:19
  • 5
    @Stephen: Вы, конечно, правы. Наверное, я видел, как многие люди ошибались в этой теме, и я стал счастливым. Мои извинения. – Grodriguez 19 October 2010 в 15:31

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

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

См. документацию по методу ReadableByteChannel.read(ByteBuffer) (что также относится к FileChannel.read(ByteBuffer)). Предполагая, что канал находится в режиме блокировки, единственная гарантия заключается в том, что будет прочитан хотя бы один байт.

1
ответ дан Grodriguez 23 August 2018 в 02:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: