Как узнать дату и время создания и изменения файла в Python?
У меня есть script, который должен делать некоторые вещи на основе дат создания и модификации файлов, но должен работать в Linux и Windows. Какой лучший кросс-платформенный способ получить создание файла и дату/время изменения в Python?
Вы не можете получить время создания файла кросс-платформенным способом. См. Docs.python.org/library/os.path.html#os.path.getctime
12 ответов
Получение какой — то дате изменения в кросс-платформенной способ легко — просто позвоните os.path.getmtime(path) , и вы получите Unix метку, когда файл на path последнего изменения.
С другой стороны, получение дат создания файлов является неудобным и зависящим от платформы, отличающимся даже между тремя большими ОС:
- В Windows хранится дата создания файла ctime (задокументированная на https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx). Вы можете получить доступ к этому в Python через os.path.getctime() или атрибут .st_ctime результата вызова os.stat() . Это не будет работать в Unix, где ctime — это последний раз, когда атрибуты файла или контент были изменены.
- На Mac, а также на некоторых других ОС, основанных на Unix, вы можете использовать атрибут .st_birthtime результата вызова os.stat() .
- В Linux это невозможно, по крайней мере, без написания расширения C для Python. Хотя некоторые файловые системы, обычно используемые с Linux , st_crtime даты создания хранилища (например, ext4 хранит их в st_crtime ), ядро Linux не имеет доступа к ним; в частности, структуры, которые он возвращает из вызовов stat() в C, начиная с последней версии ядра, не содержат полей даты создания. Вы также можете видеть, что идентификатор st_crtime настоящее время не присутствует нигде в источнике Python. По крайней мере, если вы находитесь на ext4 , данные прикрепляются к inodes в файловой системе, но нет удобного способа доступа к нему. Следующая лучшая вещь на Linux является доступ к файлу mtime , либо через os.path.getmtime() или .st_mtime атрибуту os.stat() результата. Это даст вам последний раз, когда содержимое файла было изменено, что может быть достаточно для некоторых случаев использования.
Объединяя все это, кросс-платформенный код должен выглядеть примерно так.
import os import platform def creation_date(path_to_file): """ Try to get the date that a file was created, falling back to when it was last modified if that isn't possible. See http://stackoverflow.com/a/39501288/1709587 for explanation. """ if platform.system() == 'Windows': return os.path.getctime(path_to_file) else: stat = os.stat(path_to_file) try: return stat.st_birthtime except AttributeError: # We're probably on Linux. No easy way to get creation dates here, # so we'll settle for when its content was last modified. return stat.st_mtime
Я приложил все усилия, чтобы собрать все это вместе (и потратил несколько часов на изучение процесса), и я уверен, что это по крайней мере более правильно, чем ответы, которые были здесь ранее, но это действительно сложная тема, и я ‘ Буду признателен за любые исправления, разъяснения или другие материалы, которые могут предложить люди. В частности, я хотел бы создать способ доступа к этим данным на дисках ext4 под Linux, и я хотел бы узнать, что происходит, когда Linux читает файлы, написанные Windows, или наоборот, учитывая, что они используют st_ctime другому.
Честно говоря, время создания файла обычно довольно бесполезно. Когда вы открываете существующий файл для записи в режиме «w» , он не заменяет его, он просто открывает существующий файл и усекает его. Даже несмотря на то, что содержимое файла совершенно не связано с тем, что оно имело при создании, вам все равно сказали бы, что файл «создан» задолго до текущей версии. И наоборот, редакторы, использующие атомарную замену при сохранении (исходный файл заменяется новым временным файлом незавершенного производства), будут показывать более позднюю дату создания, даже если вы только что удалили один символ. Используйте время модификации, а не время для создания.
Спустя много лет я наконец нашел время для создания файлов! Я пишу код для проверки соглашения об именовании файлов в определенных каталогах, поэтому прежде всего я хочу рассмотреть файлы, которые были впервые названы после того, как было установлено соглашение. Замена всего содержимого (mtime) не имеет значения: если он уже был там, значит, он находится в.
Привет Марк. Я предлагаю упрощение. В Linux возврат stat.st_ctime более уместен, поскольку во многих случаях время последнего изменения метаданных может быть временем создания (по крайней мере, ctime ближе к реальному времени создания, чем mtime ). Следовательно, вы можете просто заменить свой фрагмент на stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime . Как вы думаете? ура
@olibre «по крайней мере ctime ближе к реальному времени создания, чем mtime» — нет, это не так; это то, что я видел, заявлено несколько раз, но это полностью неверно. Если вы вручную не запутались со значениями в вашем inode, ctime всегда должно быть равно или позже mtime , потому что изменение mtime вызывает изменение ctime (потому что само mtime считается «метаданными»). См. Stackoverflow.com/a/39521489/1709587, где я приведу пример кода, чтобы проиллюстрировать это.
Всякий раз, когда st_ctime , нам нужны эти отвратительные заявления о различном значении в Windows, и это приводит к некрасивому коду, даже если ctime используется редко. Я хотел бы изменить реализацию os.stat в Windows для поддержки st_birthtime в дополнение к st_ctime , но не рекомендуется использовать st_ctime в качестве «времени создания». Переменная окружения позволила бы использовать st_ctime качестве времени изменения (поддерживается NTFS; нам пришлось бы изменить запросы, используемые для реализации os.stat ), что впоследствии станет значением по умолчанию в следующей версии.
Если файлы являются изображениями, вы также можете получить попытку получить полученную дату, используя PIL: `из импорта PIL Image def get_date_taken (path): try: return Image.open (path) ._ getexif () [36867] кроме: return os .path.getmtime (путь) `
У вас есть несколько вариантов. Во-первых, вы можете использовать os.path.getmtime и os.path.getctime функции:
import os.path, time print("last modified: %s" % time.ctime(os.path.getmtime(file))) print("created: %s" % time.ctime(os.path.getctime(file)))
Другой вариант — использовать os.stat :
import os, time (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file) print("last modified: %s" % time.ctime(mtime))
Примечание: ctime() не относится к времени создания в системах * nix, а скорее в последний раз, когда изменились данные inode. (спасибо kojiro за то, что этот факт более ясен в комментариях, предоставив ссылку на интересный пост в блоге)
На всякий случай, если кто-то пропустит комментарий @ Glyph к этому вопросу, ctime не означает время создания в системах POSIX . Интересно, сколько людей просмотрели этот пост за последние три года и начали писать глючный код.
@kojiro сообщение в блоге, на которое вы ссылаетесь, может быть более явным, чем когда в Unix ctime файла обновляется всякий раз, когда mtime делает это (поскольку mtime — «метаданные»), и поэтому ctime обычно всегда равно или опережает mtime , ctime как «созданное» время не имеет никакого смысла. -1!
Лучшая функция для этого — os.path.getmtime(). Внутри это просто использует os.stat(filename).st_mtime .
Модуль datetime — лучший способ создания временных меток, поэтому вы можете получить дату изменения как объект datetime следующим образом:
import os import datetime def modification_date(filename): t = os.path.getmtime(filename) return datetime.datetime.fromtimestamp(t)
>>> d = modification_date('/var/log/syslog') >>> print d 2009-10-06 10:50:01 >>> print repr(d) datetime.datetime(2009, 10, 6, 10, 50, 1)
Этот ответ также немного неверен. getmtime — самая близкая вещь, доступная в Unix (где получение дат создания невозможно), но определенно не самая лучшая функция для использования в Windows, где ctime — время создания.
edit: в новом коде вы, вероятно, должны использовать os.path.getmtime() (спасибо Кристиан Оудард)
но обратите внимание, что он возвращает значение с плавающей запятой time_t с долей секунд (если ваша ОС поддерживает его)
Предложение «в новом коде» здесь немного вводит в заблуждение. os.path.getmtime() существует с Python 1.5.2 (см. старые документы ), выпущенного до того, как я потерял большинство своих молочных зубов, и почти за десять лет до того, как вы написали оригинальную версию этого ответа.
Есть два способа получить время mod, os.path.getmtime() или os.stat(), но ctime не является надежной кросс-платформенной (см. ниже).
os.path.getmtime()
getmtime (путь)
Верните время последней модификации пути. Возвращаемое значение — это число, дающее количество секунд с эпохи (см. модуль времени). Поднять os.error, если файл не существует или недоступен. Новое в версии 1.5.2. Изменено в версии 2.3: Если os.stat_float_times() возвращает значение True, результатом является число с плавающей запятой.
os.stat()
stat (путь)
Выполните системный вызов stat() по данному пути. Возвращаемое значение — это объект, чья атрибуты соответствуют членам структуры stat, а именно: st_mode (защита бит), st_ino (номер inode), st_dev (устройство), st_nlink (количество жестких ссылок), st_uid (идентификатор пользователя владельца), st_gid (идентификатор группы владельца), st_size (размер файла, в байтах), st_atime (время последнего доступа), st_mtime (время последнего содержимого модификация), st_ctime (зависит от платформы; время последнего изменения метаданных в Unix или время создания в Windows):
>>> import os >>> statinfo = os.stat('somefile.txt') >>> statinfo (33188, 422511L, 769L, 1, 1032, 100, 926L, 1105022698,1105022732, 1105022732) >>> statinfo.st_size 926L >>>
В приведенном выше примере вы должны использовать statinfo.st_mtime или statinfo.st_ctime для получения mtime и ctime соответственно.
Получение даты создания и изменения файла в Python
Существуют случаи, когда возникает потребность получить информацию о дате создания и последнего изменения файла. Это может быть полезно во многих контекстах, например, при создании скриптов для автоматического архивирования файлов или при работе с системами управления версиями.
В Python есть несколько способов получить эту информацию, причем большинство из них являются кросс-платформенными и будут работать как на Linux, так и на Windows.
Самый простой и распространенный способ — использование встроенного модуля os . Этот модуль содержит функцию os.path.getmtime() , которая возвращает время последнего изменения файла в виде числа с плавающей точкой, представляющего секунды с начала эпохи (обычно это 01.01.1970 г.).
import os filename = "test.txt" mtime = os.path.getmtime(filename) print(mtime)
Этот код вернет время последнего изменения файла «test.txt». Чтобы преобразовать это время из секунд с начала эпохи в более читаемый формат, можно использовать функцию datetime.fromtimestamp() :
import os from datetime import datetime filename = "test.txt" mtime = os.path.getmtime(filename) mtime_readable = datetime.fromtimestamp(mtime) print(mtime_readable)
Получение времени создания файла немного сложнее и отличается в зависимости от операционной системы. На Windows можно использовать функцию os.path.getctime() , которая работает аналогично os.path.getmtime() , но возвращает время создания файла. На Linux, к сожалению, такой функции нет, поэтому придется использовать функцию os.stat() , которая возвращает объект с метаданными файла, включая время его создания.
import os from datetime import datetime filename = "test.txt" stat = os.stat(filename) ctime = stat.st_ctime ctime_readable = datetime.fromtimestamp(ctime) print(ctime_readable)
Таким образом, получение информации о времени создания и изменения файла в Python — это относительно простая задача, которая может быть выполнена с помощью встроенного модуля os .