У меня есть сценарий, который должен выполнять некоторые действия в зависимости от дат создания и изменения файлов, но должен работать в Linux и Windows.
Какой лучший кроссплатформенный способ создания и изменения файлов date/times
в Python?
У меня есть сценарий, который должен выполнять некоторые действия в зависимости от дат создания и изменения файлов, но должен работать в Linux и Windows.
Какой лучший кроссплатформенный способ создания и изменения файлов date/times
в Python?
В Python 3.4 и выше вы можете использовать объектно-ориентированный интерфейс pathlib module, который включает оболочки для большей части модуля ОС. Вот пример получения статистики файла.
>>> 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
:
>>> import datetime
>>> mtime = datetime.datetime.fromtimestamp(fname.stat().st_mtime)
>>> print(mtime)
datetime.datetime(2018, 10, 17, 10, 49, 0, 249980)
Если вам нужно время создания в Windows или самое последнее изменение метаданных в Unix, вы должны использовать fname.stat().st_ctime
:
>>> ctime = datetime.datetime.fromtimestamp(fname.stat().st_ctime)
>>> print(ctime)
datetime.datetime(2018, 4, 11, 16, 57, 52, 151953)
В этой статье есть дополнительная полезная информация и примеры для модуля pathlib.
Получить какую-либо дату модификации кроссплатформенным способом легко - просто вызовите os.path.getmtime(path)
, и вы получите отметку времени Unix, когда файл по адресу path
был в последний раз изменен.
С другой стороны, получение дат создания файлов сложно и зависит от платформы, и они различаются даже между тремя большими ОС:
ctime
файла (задокументировано по адресу https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx) хранит дату его создания. Вы можете получить доступ к этому в Python через os.path.getctime()
или < атрибут href = "https://docs.python.org/3/library/os.html#os.stat_result.st_ctime" rel = "noreferrer"> _ 5_ результата вызова _ 6_. Это не работает в Unix, где ctime
- это последний раз, когда атрибуты файла или изменялись.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
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
по-разному.
- person Mark Amery; 15.09.2016
"w"
, он не заменяет его, он просто открывает существующий файл и обрезает его. Несмотря на то, что содержимое файла совершенно не связано с тем, что он имел при создании, вам все равно скажут, что файл был создан задолго до текущей версии. И наоборот, редакторы, которые используют атомарную замену при сохранении (исходный файл заменяется новым временным файлом в процессе), будут отображать более позднюю дату создания, даже если вы просто удалили один символ. Используйте время модификации, не тратите время на создание.
- person ShadowRanger; 17.10.2016
stat.st_ctime
равно более уместно, потому что во многих случаях время последнего изменения метаданных может быть временем создания (по крайней мере ctime
ближе к реальному времени создания, чем mtime
). Поэтому вы можете просто заменить свой фрагмент на stat = os.stat(path_to_file); try: return stat.st_birthtime; except AttributeError: return stat.st_ctime
. Что вы думаете? Ваше здоровье
- person oHo; 07.08.2017
ctime
всегда должно быть равно или позже, чем mtime
, потому что изменение mtime
вызывает изменение ctime
(поскольку mtime
сам считается метаданными). См. stackoverflow.com/a/39521489/1709587, где я привожу пример кода, чтобы проиллюстрировать это.
- person Mark Amery; 09.08.2017
st_ctime
, нам нужны эти уродливые заявления об отказе от ответственности о различном значении в Windows, и это делает уродливый код, даже если ctime
редко используется. Я хотел бы изменить реализацию os.stat
в Windows для поддержки st_birthtime
в дополнение к st_ctime
, но отказаться от использования st_ctime
в качестве времени создания. Переменная среды позволит использовать st_ctime
в качестве времени изменения (поддерживается NTFS; нам пришлось бы изменить запросы, используемые для реализации os.stat
), что впоследствии будет сделано по умолчанию в следующей версии.
- person Eryk Sun; 10.07.2018
statx
делает i > разрешить запросы btime
, если они доступны для данного файла. (Однако это не используется / не отображается даже в Python 3.8.)
- person ntninja; 05.01.2020
У вас есть несколько вариантов. Например, вы можете использовать os.path.getmtime
и _ 2_ функции:
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 за то, что он разъяснил этот факт в комментариях, предоставив ссылку на интересный пост в блоге)
ctime
обновляется всякий раз, когда это делает mtime
(поскольку mtime
является метаданными), и поэтому ctime
обычно всегда равно или опережает < / i> mtime
. Таким образом, трактовка ctime
как созданного времени вообще не имеет смысла. -1!
- person Mark Amery; 12.09.2016
Last modified: Fri Jan 31 11:08:13 2020
и Created: Fri Jan 31 11:08:13 2020
в Linux Ubuntu 16.04!
- person Färid Alijani; 31.01.2020
time.ctime(os.path.getmtime(file))
возвращает 2 типа строк, в зависимости от того, был ли файл изменен системой или пользователем. Если он был изменен системой, в строке будет два пробела между месяцем и днем. Я не знаю почему
- person Matteo Antolini; 10.04.2020
Лучшая функция для этого - 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
- время создания.
- person Mark Amery; 12.09.2016
os.stat https://docs.python.org/2/library/stat.html#module-stat
изменить: в новом коде вам, вероятно, следует использовать os.path.getmtime () (спасибо Christian Oudard), но обратите внимание, что он возвращает значение time_t с плавающей запятой с долями секунд (если ваша ОС поддерживает это)
os.path.getmtime()
существует с Python 1.5.2 (см. старые документы), выпущенный до того, как я потерял большую часть молочных зубов, и почти за десять лет до того, как вы написали исходную версию этого ответа.
- person Mark Amery; 12.09.2016
Есть два метода получения времени модификации: os.path.getmtime () или os.stat (), но ctime не является надежным кроссплатформенным (см. Ниже).
getmtime (path)
Возвращает время последнего изменения пути. Возвращаемое значение - это число, указывающее количество секунд с начала эпохи (см. Модуль времени). Поднимите os.error, если файл не существует или недоступен. Новое в версии 1.5.2. Изменено в версии 2.3: если os.stat_float_times () возвращает True, результатом будет число с плавающей запятой.
stat (path)
Выполнить системный вызов 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 соответственно.
import os, time, datetime
file = "somefile.txt"
print(file)
print("Modified")
print(os.stat(file)[-2])
print(os.stat(file).st_mtime)
print(os.path.getmtime(file))
print()
print("Created")
print(os.stat(file)[-1])
print(os.stat(file).st_ctime)
print(os.path.getctime(file))
print()
modified = os.path.getmtime(file)
print("Date modified: "+time.ctime(modified))
print("Date modified:",datetime.datetime.fromtimestamp(modified))
year,month,day,hour,minute,second=time.localtime(modified)[:-3]
print("Date modified: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))
print()
created = os.path.getctime(file)
print("Date created: "+time.ctime(created))
print("Date created:",datetime.datetime.fromtimestamp(created))
year,month,day,hour,minute,second=time.localtime(created)[:-3]
print("Date created: %02d/%02d/%d %02d:%02d:%02d"%(day,month,year,hour,minute,second))
отпечатки
somefile.txt
Modified
1429613446
1429613446.0
1429613446.0
Created
1517491049
1517491049.28306
1517491049.28306
Date modified: Tue Apr 21 11:50:46 2015
Date modified: 2015-04-21 11:50:46
Date modified: 21/04/2015 11:50:46
Date created: Thu Feb 1 13:17:29 2018
Date created: 2018-02-01 13:17:29.283060
Date created: 01/02/2018 13:17:29
os.stat
возвращает именованный кортеж с атрибутами st_mtime
и st_ctime
. Время модификации st_mtime
на обеих платформах; к сожалению, в Windows ctime
означает «время создания», тогда как в POSIX это означает «время изменения». Я не знаю ни одного способа узнать время создания на платформах POSIX.
dir(..)
на одном. Например. dir(os.stat(os.listdir('.')[0]))
- person Evgeni Sergeev; 16.10.2013
Возможно, стоит взглянуть на библиотеку 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
debugfs
в Linux, который по определению нестабилен, требует корневого доступа верхнего уровня для всего и почти во всех аспектах имеет тенденцию быть одной из тех вещей, о которых ваша мать всегда предупреждала вас. (Но да, это, вероятно, сработает, если вы действительно в отчаянии и оказались настоящим суперпользователем в системе без безопасной загрузки…)
- person ntninja; 08.01.2020
Если переход по символическим ссылкам не важен, вы также можете использовать встроенный os.lstat
.
>>> os.lstat("2048.py")
posix.stat_result(st_mode=33188, st_ino=4172202, st_dev=16777218L, st_nlink=1, st_uid=501, st_gid=20, st_size=2078, st_atime=1423378041, st_mtime=1423377552, st_ctime=1423377553)
>>> os.lstat("2048.py").st_atime
1423378041.0
os.stat
включает время создания. Просто нет определения st_anything для элемента os.stat()
, который содержит время.
Так что попробуйте это:
os.stat('feedparser.py')[8]
Сравните это с датой создания файла в ls -lah
Они должны быть такими же.
Мне удалось узнать время создания на posix, выполнив системную команду stat и проанализировав вывод.
commands.getoutput('stat FILENAME').split('\"')[7]
Выполнение статистики вне Python из Терминала (OS X) вернуло:
805306374 3382786932 -rwx------ 1 km staff 0 1098083 "Aug 29 12:02:05 2013" "Aug 29 12:02:05 2013" "Aug 29 12:02:20 2013" "Aug 27 12:35:28 2013" 61440 2150 0 testfile.txt
... где четвертое datetime - это создание файла (а не время изменения ctime, как отмечалось в других комментариях).
pathlib
вместоos
, см. Ответ @ StevenC.Howell. Возможно, можно было бы даже изменить принятый ответ наpathlib
ответ? - person questionto42   schedule 30.11.2020