Как работает функция поиска Python?

Если у меня есть файлоподобный объект и я делаю следующее:

F = open('abc', 'r')
...
loc = F.tell()
F.seek(loc-10)

Что делает поиск? Начинается ли он с начала файла и читает loc-10 байта? Или он достаточно умен, чтобы просто сделать резервную копию 10 байт?


person jlconlin    schedule 07.11.2012    source источник


Ответы (5)


Это зависит от ОС и libc. операция file.seek() делегируется вызову fseek(3) C для реальных файлов уровня ОС.

person Ignacio Vazquez-Abrams    schedule 07.11.2012
comment
Так зависит ли эта платформа и реализация? - person jlconlin; 08.11.2012
comment
Да, с реализацией, разделенной между libc и ОС. - person Ignacio Vazquez-Abrams; 08.11.2012
comment
Так возможно ли/легко сделать это, не начиная с начала файла? - person jlconlin; 08.11.2012
comment
На большинстве платформ позиция в файле — это просто число, хранящееся в таблице дескрипторов файлов; нет никакого поиска физического диска. Так что нет причин просто делать резервную копию 10 байт. Когда вы выполняете следующее чтение или запись, именно здесь libc/OS/файловая система может быть умной и понять, что вы читаете из блока, который все еще находится в кеше и вообще не читается, или читаете предыдущий блок, поэтому ему нужно только искать один блок (в любом случае это различие не имеет значения на современном диске — предыдущий виртуальный блок может быть, скажем, на другом физическом диске в вашем массиве LVM…). - person abarnert; 08.11.2012
comment
Кроме того, обратите внимание, что это fseek, а не lseek, что означает, что FILE* управляется libc поверх того, что есть в ОС, а FILE*, вероятно, имеет свою собственную позицию и буфер, поэтому, возможно, ему даже не нужно переходить к ОС/файловая система для последующего чтения. - person abarnert; 08.11.2012

Согласно документам Python 2.7:

file.seek(offset[, whence])

Установите текущую позицию файла, например fseek() в stdio. Аргумент откуда является необязательным и по умолчанию равен os.SEEK_SET или 0 (абсолютное позиционирование файла); другими значениями являются os.SEEK_CUR или 1 (поиск относительно текущей позиции) и os.SEEK_END или 2 (поиск относительно конца файла).

Скажем, вы хотели бы вернуться на 10 байтов назад относительно вашей позиции:

file.seek(-10, 1)
person TankorSmash    schedule 07.11.2012

Это должно быть достаточно умно, чтобы просто создать резервную копию 10 байтов, но я полагаю, что детали действительно зависят от используемой вами файловой системы/ОС/библиотеки времени выполнения.

Обратите внимание, что если вы просто хотите создать резервную копию 10 байт, tell не требуется.

F.seek(-10,1)
person mgilson    schedule 07.11.2012
comment
Спасибо, что поделились этим. Это гораздо более простая реализация, чем я привел в качестве примера. - person jlconlin; 08.11.2012

file.seek() set the current read/write position.
file.tell() Returns the file's current position.

Итак, когда вы сделали **loc = F.tell()**, вы сохранили текущую позицию в файле в переменной loc.

И **file.seek()** принимает два аргумента **file.seek(offset, from)**

Поэтому вам нужно определить, откуда вы хотите сместить файл. **from** принимает одно из следующих значений 0,1,2 (0 = начало, 1 = текущий, 2 = конец)

Так вот как это работает.

person Ayemun Hossain Ashik    schedule 01.12.2019

по документации нужно сделать f.seek(offset, from_what), или в вашем случае F.seek(-10, loc)

ваш пример должен работать, но это более явно

person RobL    schedule 07.11.2012
comment
Это вводит в заблуждение. Этот ответ работает, только если loc равно 1. - person mgilson; 08.11.2012