Tell: примеры (PYTHON)

Метод tell в Python: получение позиции в файловых объектах
Раздел: Файлы, Позиционирование
tell: int

Основные характеристики метода tell

Метод tell() является частью объектов файлов в Python и применяется для получения текущей позиции указателя чтения-записи в файле. Эта позиция измеряется в байтах от начала файла. Использование метода не изменяет состояние файлового объекта.

Возвращаемое значение - целое число, обозначающее количество байтов от начала файла до текущей позиции указателя. Для текстовых файлов, открытых в режимах, подразумевающих преобразование (например, с указанием кодировки), возвращаемое значение может не соответствовать количеству считанных символов из-за различий в размере символов в байтах.

Метод не принимает аргументов и работает только с файловыми объектами, открытыми для чтения или записи. Его вызов на закрытом файле вызывает исключение ValueError.

Простые примеры применения

Пример с текстовым файлом в кодировке UTF-8:

with open('test.txt', 'w', encoding='utf-8') as f:
    f.write('Привет')

with open('test.txt', 'r', encoding='utf-8') as f:
    print(f.tell())  # 0
    f.read(2)
    print(f.tell())  # 4 (так как кириллические символы занимают 2 байта каждый)
0
4

Пример с бинарным файлом:

with open('test.bin', 'wb') as f:
    f.write(b'\x01\x02\x03\x04')
    print(f.tell())  # 4

with open('test.bin', 'rb') as f:
    print(f.tell())  # 0
    f.read(2)
    print(f.tell())  # 2
4
0
2

Аналогичные методы в Python

Метод seek(offset, whence) изменяет позицию указателя в файле. Принимает два аргумента: смещение и точку отсчета. Часто используется вместе с tell() для запоминания и восстановления позиции.

Метод file.seekable() проверяет поддержку случайного доступа к файлу. Если возвращает False, методы tell() и seek() могут быть недоступны.

Для потоков ввода-вывода из модуля io (например, StringIO, BytesIO) также существуют методы tell() и seek() с аналогичной функциональностью.

Аналоги в других языках программирования

В PHP функция ftell() возвращает текущую позицию в файловом указателе. Отличие: работает только с ресурсами файлов.

$fp = fopen('test.txt', 'r');
fread($fp, 3);
echo ftell($fp);  // 3
fclose($fp);
3

В JavaScript (Node.js) метод filehandle.read() не предоставляет прямого аналога. Позицию можно получить через filehandle.read() с опцией position или использовать fs.statSync для размера.

В Java метод getFilePointer() класса RandomAccessFile возвращает текущее смещение в файле. Похож на Python, но работает только с этим классом.

RandomAccessFile file = new RandomAccessFile("test.txt", "r");
file.readByte();
long pos = file.getFilePointer();  // 1
file.close();
1

В C# свойство Position у классов FileStream или StreamReader позволяет получить или установить позицию. Отличие: это свойство, а не метод.

using (FileStream fs = new FileStream("test.txt", FileMode.Open))
{
    fs.ReadByte();
    Console.WriteLine(fs.Position);  // 1
}
1

Распространенные ошибки

Вызов метода на закрытом файловом объекте вызывает исключение:

f = open('test.txt', 'r')
f.close()
print(f.tell())
ValueError: I/O operation on closed file.

Некорректная интерпретация позиции для текстовых файлов с многобайтовыми символами:

with open('test.txt', 'w', encoding='utf-8') as f:
    f.write('αβγ')  # греческие буквы

with open('test.txt', 'r', encoding='utf-8') as f:
    f.read(1)
    print(f.tell())  # 2, а не 1
2

Попытка использования на не поддерживающих операциях объектах (например, сетевое соединение):

import socket
s = socket.socket()
# s.tell()  # AttributeError: 'socket' object has no attribute 'tell'

Изменения в последних версиях Python

Специфических изменений в поведении метода tell() в последних основных версиях Python (3.8-3.12) не зафиксировано. Однако, обновления, касающиеся модуля io и обработки текстовых файлов, могут косвенно влиять на возвращаемые значения в определенных кодировках.

В Python 3.7 улучшена производительность некоторых файловых операций, что могло затронуть и работу tell() для стандартных файловых объектов.

Расширенные сценарии использования

Запоминание позиции для последующего возврата:

Пример python
with open('data.txt', 'r') as f:
    start_pos = f.tell()
    chunk1 = f.read(10)
    saved_pos = f.tell()
    chunk2 = f.read(20)
    f.seek(saved_pos)  # возврат к сохраненной позиции
    chunk2_again = f.read(20)
    print(chunk2 == chunk2_again)  # True
True

Использование с бинарными файлами и структурой данных:

Пример python
import struct
with open('data.bin', 'wb') as f:
    f.write(struct.pack('i', 42))  # запись целого числа
    print(f.tell())  # 4 (размер int в байтах)

with open('data.bin', 'rb') as f:
    while f.tell() < 4:
        data = f.read(1)
        print(f"Position: {f.tell()}, Data: {data}")
4
Position: 1, Data: b'*'
Position: 2, Data: b'\x00'
Position: 3, Data: b'\x00'
Position: 4, Data: b'\x00'

Обработка большого файла с периодическим сохранением позиции:

Пример python
import time
with open('large.log', 'r') as f:
    last_pos = 0
    while True:
        f.seek(last_pos)
        new_lines = f.readlines(5)  # чтение по частям
        if not new_lines:
            break
        last_pos = f.tell()
        print(f"Read {len(new_lines)} lines from position {last_pos}")
        time.sleep(0.1)

питон tell function comments

En
Tell Return current stream position