Я использую Windows 7 — 64-битную версию с последней версией XAMPP, которая имеет 32-битную версию PHP.
На тестировании http://php.net/manual/en/function.fseek.php#112647
для очень большого файла (больше, чем PHP_MAX_INT 2147483647) Теперь я почти уверен, что последовательно следующие fseeks суммируются перед выполнением в указателе файла.
У меня есть два вопроса:
Могу ли я разбить это обобщение разумными средствами (или только с помощью обходного пути, упомянутого в ссылке выше)?
Это агрегация происходит в PHP (как я предполагаю, хотя я не знаю, где в PHP) или в Windows 7?
Отвечаю себе: пробовать два обходных пути с несколькими поисками не получилось
в моей системе. Вместо этого они помещают указатель файла в разные позиции
в под PHP_MAX_INT. (Только 32-битный PHP может искать до PHP_MAX_INT +
8192. Чтение еще возможно, но я не знаю, как далеко.)Поэтому вопрос устарел для моего конкретного случая, так как
Только 32-битный PHP может искать до PHP_MAX_INT + 8192, что бы вы ни делали. я
оставьте вопрос, потому что два человека проголосовали за него, и может быть
интересует общий ответ.
Я подал отчет об ошибке здесь:
https://bugs.php.net/bug.php?id=69213
Результат: с 64-битной сборкой PHP это может сработать, но я не пробовал.
Это не так. Это на самом деле делает что-то даже тупее. Вот фрагмент из исходного кода PHP:
switch(whence) {
case SEEK_CUR:
offset = stream->position + offset;
whence = SEEK_SET;
break;
}
Это в сущности реализации для PHP fseek
, Здесь происходит следующее: если вы указываете PHP выполнять поиск с текущей позиции, он переводит это в «эквивалентный» поиск с начала файла. Это работает только тогда, когда это вычисление смещения не переполняется; если да, то offset
целое число со знаком, так что это неопределенное поведение.
И, ладно, это происходит потому, что PHP буферизует потоки внутри, поэтому они должны сделать что-то. Но это не должно быть так.
Возможно, вам лучше всего делать свою работу на языке, который на самом деле делает то, что вы говорите.
Если бы агрегация происходила, это, вероятно, должно было бы быть оптимизацией кода операции или происходило бы на низком уровне через буфер.
Я могу ответить на низком уровне. Функция fseek () в php реализована с использованием потоков php. Он объявлен в ext / standard / file.h и определен в .c. Его реализация вызывает php_stream_seek (), которая вызывает _php_stream_seek () в streams.c. Низкоуровневая реализация этого обрабатывается через оболочку простых потоков, в этом случае ищите вызовы либо к zend_seek, либо к zend_fseek, которые, в свою очередь, просто отображаются на 32- или 64-битные. искать _seeki64 c звонками.
Так что … если произойдет какое-либо агрегирование, похоже, что оно должно быть в оптимизации кода операции или даже ниже в ОС или оборудовании. На жестких дисках реализована выборочная сортировка для уменьшения расстояний между заголовками, а системы буферизации файловой системы могут уменьшить число запросов, не имеющих побочных эффектов. Если вас беспокоит время чтения с диска, первый автоматически это решит. Если вы обеспокоены, возможно, перегрузкой памяти (ищите большие расстояния без необходимости в буфере), вы могли бы рассмотреть другой подход. Увидеть: http://www.cs.iit.edu/~cs561/cs450/disksched/disksched.html для получения дополнительной информации о том, как диски избегают тратить время на поиск.
Надеюсь, это поможет.