Получить какую-то дату модификации кроссплатформенным способом легко - просто позвоните, и вы получите метку времени Unix, когда файл был последний раз изменен.os.path.getmtime(path)path
Получение дат создания файла , с другой стороны, зависит от платформы и зависит даже от трех больших ОС:
На Mac , как и на некоторых других Unix-системах, вы можете использовать .st_birthtimeатрибут результата вызова os.stat().
В Linux это в настоящее время невозможно, по крайней мере без написания расширения C для Python. Хотя некоторые файловые системы, обычно используемые в Linux , хранят даты создания (например, ext4хранят их в st_crtime), ядро Linux не предлагает никакого доступа к ним ; в частности, структуры, которые он возвращает из stat()вызовов в C, начиная с последней версии ядра, не содержат никаких полей даты создания . Вы также можете видеть, что этот идентификатор в st_crtimeнастоящее время отсутствует в источнике Python . По крайней мере , если вы на ext4, данные в прикрепляются к дескрипторам в файловой системе, но нет удобного способа доступа к нему.
Следующая лучшая вещь на 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
exceptAttributeError:# 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разному.
Марк Амери
25
Честно говоря, время создания файла обычно довольно бесполезно. Когда вы открываете существующий файл для записи в режиме "w", он не заменяет его, он просто открывает существующий файл и усекает его. Даже если содержимое файла совершенно не связано с тем, что оно имело при создании, вам все равно сказали бы, что файл «создан» задолго до текущей версии. И наоборот, редакторы, использующие атомарную замену при сохранении (исходный файл заменяется новым временным файлом, находящимся в процессе выполнения), будут отображать более позднюю дату создания, даже если вы только что удалили один символ. Используйте время модификации, а не время для создания.
ShadowRanger
3
Спустя много лет я наконец нашел применение времени создания файлов! Я пишу код для проверки соглашения об именовании файлов в определенных каталогах, поэтому прежде всего я хочу рассмотреть файлы, которые были впервые названы после того, как было установлено соглашение. Замена всего содержимого (mtime) не имеет значения: если он уже был там, значит, он в нем работает.
Steve Jessop
1
Привет Марк. Я предлагаю упрощение. В Linux возврат stat.st_ctimeболее уместен, поскольку во многих случаях время последнего изменения метаданных может быть временем создания (по крайней мере ctime, ближе к реальному времени создания, чем mtime). Поэтому вы можете просто заменить свой фрагмент на stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime. Что вы думаете? Приветствия
olibre
4
@olibre "по крайней мере ctime ближе к реальному времени создания, чем mtime" - нет, это не так; это то, что я видел, заявлено несколько раз, но это полностью неверно. Если вы не вручную перепутались со значениями в вашем иноду ctimeвсегда должна быть равна или позже , чем mtime, потому что mtimeизменение приводит к ctimeизменению (поскольку mtimeсам считается «метаданных»). См. Stackoverflow.com/a/39521489/1709587, где я приведу пример кода, чтобы проиллюстрировать это.
Примечание : ctime()это не относится к времени создания на * NIX систем, а последний раз , когда данные индексных дескрипторов изменились. (спасибо Кодзиро за разъяснение этого факта в комментариях, предоставив ссылку на интересную запись в блоге)
На всякий случай, если кто-то пропустит комментарий @ Glyph к этому вопросу, ctime не означает время создания в системах POSIX . Интересно, сколько людей просмотрели этот пост за последние три года и начали писать глючный код.
Кодзиро
16
Имейте в виду, что первый пример дает вам строку, а не дату или время.
Гак
1
@kojiro сообщение в блоге вы связаны с может быть более явным , что на Unix к файлу ctimeобновляется всякий раз , когда mtimeделает (так как mtimeэто «метаданные»), и поэтому , ctimeкак правило , всегда равна или больше , чемmtime . ctimeТаким образом, трактовать время как «созданное» не имеет никакого смысла. -1!
Марк Амери
Ваша первая опция возвращает одинаковые результаты как для создания файла, так и для последней модификации! Last modified: Fri Jan 31 11:08:13 2020и Created: Fri Jan 31 11:08:13 2020на Linux Ubuntu 16.04!
Ферид Алиджани
Я обнаружил, что time.ctime(os.path.getmtime(file))возвращает 2 типа строк, в зависимости от того, был ли файл изменен системой или пользователем. Если она была изменена системой, строка будет иметь 2 пробела между месяцем и днем. Я не знаю почему
Маттео Антолини
376
Лучшая функция для этого - 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-0610:50:01>>>print repr(d)
datetime.datetime(2009,10,6,10,50,1)
Этот ответ также немного неправильный. getmtimeэто самая близкая вещь, доступная в Unix (где получение дат создания невозможно), но это определенно не лучшая функция для использования в Windows, где время ctimeсоздания.
Марк Амери
3
@MarkAmery - Этот ответ четко обозначен как время модификации.
edit: в более новом коде вы, вероятно, должны использовать os.path.getmtime () (спасибо Christian Oudard),
но обратите внимание, что он возвращает значение с плавающей запятой time_t с долями секунды (если ваша ОС поддерживает это)
Предложение «в новом коде» здесь немного вводит в заблуждение. os.path.getmtime()существует с Python 1.5.2 (см. старые документы ), выпущенного до того, как я потерял большую часть своих молочных зубов, и почти за десять лет до того, как вы написали оригинальную версию этого ответа.
Марк Амери
39
Есть два метода для получения времени мода, os.path.getmtime () или os.stat (), но ctime не является надежной кроссплатформенной (см. Ниже).
getmtime ( path ) Возвращает время последней модификации пути. Возвращаемое значение - это число, указывающее количество секунд с начала эпохи (см. Модуль времени). Поднимите os.error, если файл не существует или недоступен. Новое в версии 1.5.2. Изменено в версии 2.3: если os.stat_float_times () возвращает True, результатом является число с плавающей запятой.
stat ( путь ) Выполнить системный вызов stat () по заданному пути. Возвращаемое значение - это объект, атрибуты которого соответствуют членам структуры статистики, а именно: st_mode (защитные биты), st_ino (номер индекса), 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 3.4 и выше вы можете использовать объектно-ориентированный интерфейс модуля pathlib, который включает в себя оболочки для большей части модуля os. Вот пример получения статистики по файлу.
>>>import pathlib
>>> fname = pathlib.Path('test.py')>>>assert fname.exists(), f'No such file: {fname}'# check that the file exists>>>print(fname.stat())
os.stat_result(st_mode=33206, st_ino=5066549581564298, st_dev=573948050, st_nlink=1, st_uid=0, st_gid=0, st_size=413, st_atime=1523480272, st_mtime=1539787740, st_ctime=1523480272)
Для получения дополнительной информации о том os.stat_result, что содержится, обратитесь к документации . За время модификации вы хотите fname.stat().st_mtime:
os.statвозвращает именованный кортеж st_mtimeи st_ctimeатрибуты. Время модификации st_mtimeна обеих платформах; к сожалению, в Windows это ctimeозначает «время создания», а в POSIX - «время изменения». Я не знаю ни одного способа получить время создания на платформах POSIX.
Подробнее о тегированных кортежах: stackoverflow.com/questions/2970608/… Они работают как кортежи, но попробуйте dir(..)один. Напримерdir(os.stat(os.listdir('.')[0]))
-1: То же, что и в других ответах, это не даст вам время создания файла в Windows (что, опять же, даже не упоминается в ответе).
ntninja
@ntninja ты уверен в этом? Я использую только Windows, и это абсолютно работает. Я написал этот сценарий в начале 2015 года. Я считаю, что он был более понятным, понятным, полным и понятным, чем другие здесь. (что я решил найти здесь вместо моих старых сценариев, только если было что-то новое. Нет ... это путь)
Лужа
О, я хотел сказать «… это не даст вам время создания файла, если вы не в Windows». Сожалею! Факт остается фактом, что этот ответ не является переносимым и не упоминает этот факт. (Пример вывода в Linux: pastebin.com/50r5vGBE )
ntninja
@ntninja ты собираешься рассказать всем остальным тогда?
лужа
Я уже оставил здесь несколько других комментариев, и я скоро выложу ответ, который работает и на (недавней) Linux. Но на самом деле, единственное, что не так в вашем посте, - это то, что ответ только для Windows не упоминает этот факт. В вопросе OP даже специально задавалось вопрос о совместимости Windows и Linux. Поэтому я думаю, что было бы очень полезно, если бы вы добавили эту «деталь» где-то вверху, чтобы люди не вводили в заблуждение, думая, что ctime - это то, что они ищут, ориентируясь на несколько платформ.
ntninja
2
>>>import os
>>> os.stat('feedparser.py').st_mtime
1136961142.0>>> os.stat('feedparser.py').st_ctime
1222664012.233>>>
Это даст время последнего чтения (по крайней мере, в Unix), что определенно не то, о чем просили.
Марк Амери
0
Возможно, стоит взглянуть на crtimeбиблиотеку, которая реализует кроссплатформенный доступ ко времени создания файла.
from crtime import get_crtimes_in_dir
for fname, date in get_crtimes_in_dir(".", raise_on_error=True, as_epoch=False):print(fname, date)# file_a.py Mon Mar 18 20:51:18 CET 2019
Я настоятельно рекомендую это сделать: он использует debugfsLinux, который по определению нестабилен, требует корневого доступа на высшем уровне для всего и почти во всех аспектах - одна из тех вещей, о которых ваша мама всегда предупреждала. (Но да, это, вероятно, работает, если вы действительно отчаялись и оказались настоящим суперпользователем в системе без безопасной загрузки…)
ntninja
@ntninja Я бы, вероятно, никогда не использовал бы в производстве, но это может быть полезно для "домашнего сценария".
Дельган
-2
os.statдействительно включает время создания. Просто нет определения st_anything для элемента, os.stat()который содержит время.
Неправильно! os.stat ('feedparser.py') [8] ссылается на st_mtime, а не на время создания. Пожалуйста, обратитесь к документации: docs.python.org/library/os.html#os.stat
millerdev
4
Пожалуйста, используйте .st_ctime вместо некрасивых чисел [8].
Геттли
-3
Я смог получить время создания в posix, запустив системную команду stat и проанализировав вывод.
Ответы:
Получить какую-то дату модификации кроссплатформенным способом легко - просто позвоните, и вы получите метку времени Unix, когда файл был последний раз изменен.
os.path.getmtime(path)
path
Получение дат создания файла , с другой стороны, зависит от платформы и зависит даже от трех больших ОС:
ctime
(задокументированный по адресу https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx ) хранит дату его создания. Вы можете получить доступ к этому в Python черезos.path.getctime()
или к.st_ctime
атрибуту результата вызоваos.stat()
. Это не будет работать в Unix, где вctime
последний раз менялись атрибуты или содержимое файла ..st_birthtime
атрибут результата вызоваos.stat()
.В Linux это в настоящее время невозможно, по крайней мере без написания расширения C для Python. Хотя некоторые файловые системы, обычно используемые в Linux , хранят даты создания (например,
ext4
хранят их вst_crtime
), ядро Linux не предлагает никакого доступа к ним ; в частности, структуры, которые он возвращает изstat()
вызовов в C, начиная с последней версии ядра, не содержат никаких полей даты создания . Вы также можете видеть, что этот идентификатор вst_crtime
настоящее время отсутствует в источнике Python . По крайней мере , если вы наext4
, данные в прикрепляются к дескрипторам в файловой системе, но нет удобного способа доступа к нему.Следующая лучшая вещь на Linux является доступ к файлу
mtime
, либо черезos.path.getmtime()
или в.st_mtime
атрибутеos.stat()
результата. Это даст вам последний раз, когда содержимое файла было изменено, что может быть достаточно для некоторых случаев использования.Собирая все это вместе, кросс-платформенный код должен выглядеть примерно так ...
источник
ext4
дисках под Linux, и я хотел бы узнать, что происходит, когда Linux читает файлы, написанные Windows, или наоборот, учитывая, что они используют по-st_ctime
разному."w"
, он не заменяет его, он просто открывает существующий файл и усекает его. Даже если содержимое файла совершенно не связано с тем, что оно имело при создании, вам все равно сказали бы, что файл «создан» задолго до текущей версии. И наоборот, редакторы, использующие атомарную замену при сохранении (исходный файл заменяется новым временным файлом, находящимся в процессе выполнения), будут отображать более позднюю дату создания, даже если вы только что удалили один символ. Используйте время модификации, а не время для создания.stat.st_ctime
более уместен, поскольку во многих случаях время последнего изменения метаданных может быть временем создания (по крайней мереctime
, ближе к реальному времени создания, чемmtime
). Поэтому вы можете просто заменить свой фрагмент наstat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime
. Что вы думаете? Приветствияctime
всегда должна быть равна или позже , чемmtime
, потому чтоmtime
изменение приводит кctime
изменению (посколькуmtime
сам считается «метаданных»). См. Stackoverflow.com/a/39521489/1709587, где я приведу пример кода, чтобы проиллюстрировать это.У вас есть несколько вариантов. С одной стороны , вы можете использовать
os.path.getmtime
иos.path.getctime
функцию:Другой вариант - использовать
os.stat
:Примечание :
ctime()
это не относится к времени создания на * NIX систем, а последний раз , когда данные индексных дескрипторов изменились. (спасибо Кодзиро за разъяснение этого факта в комментариях, предоставив ссылку на интересную запись в блоге)источник
ctime
обновляется всякий раз , когдаmtime
делает (так какmtime
это «метаданные»), и поэтому ,ctime
как правило , всегда равна или больше , чемmtime
.ctime
Таким образом, трактовать время как «созданное» не имеет никакого смысла. -1!Last modified: Fri Jan 31 11:08:13 2020
иCreated: Fri Jan 31 11:08:13 2020
на Linux Ubuntu 16.04!time.ctime(os.path.getmtime(file))
возвращает 2 типа строк, в зависимости от того, был ли файл изменен системой или пользователем. Если она была изменена системой, строка будет иметь 2 пробела между месяцем и днем. Я не знаю почемуЛучшая функция для этого - os.path.getmtime () . Внутренне это просто использует
os.stat(filename).st_mtime
.Модуль datetime - это лучшая манипуляция с временными метками, поэтому вы можете получить дату модификации в виде
datetime
объекта:Пример использования:
источник
getmtime
это самая близкая вещь, доступная в Unix (где получение дат создания невозможно), но это определенно не лучшая функция для использования в Windows, где времяctime
создания.os.stat https://docs.python.org/2/library/stat.html#module-stat
edit: в более новом коде вы, вероятно, должны использовать os.path.getmtime () (спасибо Christian Oudard),
но обратите внимание, что он возвращает значение с плавающей запятой time_t с долями секунды (если ваша ОС поддерживает это)
источник
os.path.getmtime()
существует с Python 1.5.2 (см. старые документы ), выпущенного до того, как я потерял большую часть своих молочных зубов, и почти за десять лет до того, как вы написали оригинальную версию этого ответа.Есть два метода для получения времени мода, os.path.getmtime () или os.stat (), но ctime не является надежной кроссплатформенной (см. Ниже).
os.path.getmtime ()
getmtime ( path )
Возвращает время последней модификации пути. Возвращаемое значение - это число, указывающее количество секунд с начала эпохи (см. Модуль времени). Поднимите os.error, если файл не существует или недоступен. Новое в версии 1.5.2. Изменено в версии 2.3: если os.stat_float_times () возвращает True, результатом является число с плавающей запятой.
os.stat ()
stat ( путь )
Выполнить системный вызов stat () по заданному пути. Возвращаемое значение - это объект, атрибуты которого соответствуют членам структуры статистики, а именно: st_mode (защитные биты), st_ino (номер индекса), st_dev (устройство), st_nlink (количество жестких ссылок), st_uid (идентификатор пользователя владельца ), st_gid (идентификатор группы владельца), st_size (размер файла, в байтах), st_atime (время самого последнего доступа), st_mtime (время самой последней модификации контента), st_ctime (зависит от платформы; время самого последнего изменения метаданных в Unix или время создания в Windows) :
В приведенном выше примере вы должны использовать statinfo.st_mtime или statinfo.st_ctime, чтобы получить mtime и ctime соответственно.
источник
В Python 3.4 и выше вы можете использовать объектно-ориентированный интерфейс модуля pathlib, который включает в себя оболочки для большей части модуля os. Вот пример получения статистики по файлу.
Для получения дополнительной информации о том
os.stat_result
, что содержится, обратитесь к документации . За время модификации вы хотитеfname.stat().st_mtime
:Если вам нужно время создания в Windows или самое последнее изменение метаданных в Unix, вы должны использовать
fname.stat().st_ctime
:Эта статья содержит более полезную информацию и примеры для модуля pathlib.
источник
os.stat
возвращает именованный кортежst_mtime
иst_ctime
атрибуты. Время модификацииst_mtime
на обеих платформах; к сожалению, в Windows этоctime
означает «время создания», а в POSIX - «время изменения». Я не знаю ни одного способа получить время создания на платформах POSIX.источник
dir(..)
один. Напримерdir(os.stat(os.listdir('.')[0]))
печать
источник
источник
Если следующие символические ссылки не важны, вы также можете использовать
os.lstat
встроенную функцию.источник
Возможно, стоит взглянуть на
crtime
библиотеку, которая реализует кроссплатформенный доступ ко времени создания файла.источник
debugfs
Linux, который по определению нестабилен, требует корневого доступа на высшем уровне для всего и почти во всех аспектах - одна из тех вещей, о которых ваша мама всегда предупреждала. (Но да, это, вероятно, работает, если вы действительно отчаялись и оказались настоящим суперпользователем в системе без безопасной загрузки…)os.stat
действительно включает время создания. Просто нет определения st_anything для элемента,os.stat()
который содержит время.Итак, попробуйте это:
os.stat('feedparser.py')[8]
Сравните это с датой создания файла в ls -lah.
Они должны быть одинаковыми.
источник
Я смог получить время создания в posix, запустив системную команду stat и проанализировав вывод.
Запуск stat вне python из терминала (OS X) вернул:
... где четвертой датой является время создания файла (а не время изменения ctime, как отмечалось в других комментариях).
источник