使用Python实现触摸?
touch
是一个 Unix 实用程序,它将文件的修改和访问时间设置为当前时间。 如果该文件不存在,则会使用默认权限创建该文件。
您将如何将其实现为 Python 函数? 尝试跨平台且完整。
(当前“python touch file”的 Google 结果不是很好,但指向 os .utime。)
touch
is a Unix utility that sets the modification and access times of files to the current time of day. If the file doesn't exist, it is created with default permissions.
How would you implement it as a Python function? Try to be cross platform and complete.
(Current Google results for "python touch file" are not that great, but point to os.utime.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
我有一个用于备份的程序: https://stromberg.dnsalias.org/~strombrg /backshift/
我使用 vmprof 对其进行了分析,并发现触摸是迄今为止最耗时的部分。
所以我研究了快速触摸文件的方法。
我发现在 CPython 3.11 上,这是最快的:
在 Pypy3 7.3.9 上,这是最快的:
在两者中,pypy3 的最佳速度仅比 cpython 的最佳速度稍快。
有一天我可能会创建一个关于此的网页,但目前我拥有的只是一个 Subversion 存储库:
https://stromberg.dnsalias.org/svn/touch/trunk
它包括我尝试过的 4 种触摸方式。
I have a program that I use for backups: https://stromberg.dnsalias.org/~strombrg/backshift/
I profiled it using vmprof, and identified that touch was by far the most time-consuming part of it.
So I looked into ways of touching files quickly.
I found that on CPython 3.11, this was the fastest:
And on Pypy3 7.3.9, this was the fastest:
Of the two, pypy3's best was only slightly faster cpython's best.
I may create a web page about this someday, but for now all I have is a Subversion repo:
https://stromberg.dnsalias.org/svn/touch/trunk
It includes the 4 ways of doing touches I tried.
你为什么不尝试一下:
新文件.py
或
Why don't you try:
newfile.py
or
还有一个用于 touch 的 python 模块,
您可以使用
pip install touch
安装它There is also a python module for touch
You can install it with
pip install touch
可以使用
pathlib.Path
中的write_text()
。write_text()
frompathlib.Path
can be used.创建一个包含所需变量的字符串并将其传递给 os.system 似乎是合乎逻辑的:
这在很多方面都是不够的(例如,它不处理空格),所以不要这样做。
更可靠的方法是使用 subprocess :
subprocess.call(['touch', os.path.join(dirname, fileName)])
虽然这比使用 subshell (使用 os.subprocess )要好得多。 system),它仍然只适合快速而肮脏的脚本; 使用跨平台程序的公认答案。
It might seem logical to create a string with the desired variables, and pass it to os.system:
This is inadequate in a number of ways (e.g.,it doesn't handle whitespace), so don't do it.
A more robust method is to use subprocess :
subprocess.call(['touch', os.path.join(dirname, fileName)])
While this is much better than using a subshell (with os.system), it is still only suitable for quick-and-dirty scripts; use the accepted answer for cross-platform programs.
复杂(可能有错误):
这也尝试允许设置访问或修改时间,就像 GNU touch 一样。
Complex (possibly buggy):
This tries to also allow setting the access or modification time, like GNU touch.
以下内容就足够了:
如果您想设置触摸的特定时间,请使用 os.utime,如下所示:
这里,atime 和 mtime 都应该是 int/float,并且应该等于您想要的时间的纪元时间(以秒为单位)放。
The following is sufficient:
If you want to set a specific time for touch, use os.utime as follows:
Here, atime and mtime both should be int/float and should be equal to epoch time in seconds to the time which you want to set.
简单化:
open
确保那里有一个文件,utime
确保更新时间戳理论上,有人可能会在
open
后删除该文件>,导致 utime 引发异常。 但可以说这没关系,因为确实发生了一些不好的事情。Simplistic:
open
ensures there is a file thereutime
ensures that the timestamps are updatedTheoretically, it's possible someone will delete the file after the
open
, causing utime to raise an exception. But arguably that's OK, since something bad did happen.下面是一些使用 ctypes 的代码(仅在 Linux 上测试):
Here's some code that uses ctypes (only tested on Linux):
当关键字
with
已发布。1. 如果文件不存在则创建+设置当前时间
(与命令
touch
完全相同)更强大的版本:
2。 如果文件不存在则创建该文件
(不更新时间)
3. 只需更新文件访问/修改时间
(如果文件不存在,则不创建文件)
使用 os.path.exists() 不会简化代码:
奖励:目录中所有文件的更新时间
This answer is compatible with all versions since Python-2.5 when keyword
with
has been released.1. Create file if does not exist + Set current time
(exactly same as command
touch
)A more robust version:
2. Just create the file if does not exist
(does not update time)
3. Just update file access/modified times
(does not create file if not existing)
Using
os.path.exists()
does not simplify the code:Bonus: Update time of all files in a directory
对于更底层的解决方案,可以使用
进行比较, GNU touch 使用
,
模式
为MODE_RW_UGO
,即0o666
。For a more low-level solution one can use
For comparison, GNU touch uses
with a
mode
ofMODE_RW_UGO
, which is0o666
.为什么不尝试这个?:
我相信这消除了任何重要的竞争条件。 如果该文件不存在,则会抛出异常。
这里唯一可能的竞争条件是如果文件是在调用 open() 之前但在 os.utime() 之后创建的。 但这并不重要,因为在这种情况下,修改时间将符合预期,因为它一定是在调用 touch() 期间发生的。
Why not try this?:
I believe this eliminates any race condition that matters. If the file does not exist then an exception will be thrown.
The only possible race condition here is if the file is created before open() is called but after os.utime(). But this does not matter because in this case the modification time will be as expected since it must have happened during the call to touch().
这试图比其他解决方案更加无竞争。 (
with
关键字是 Python 2.5 中的新关键字。)大致相当于这个。
现在,要真正使其无竞争,您需要使用
futimes
并更改打开文件句柄的时间戳,而不是打开文件然后更改文件名上的时间戳(可能已重命名)。 不幸的是,Python 似乎没有提供一种无需通过ctypes
或类似的方法来调用futimes
的方法...编辑
正如 Nate Parsons,Python 3.3 将 添加 指定文件描述符 (当
os.supports_fd
时诸如os.utime
的函数,它将在底层使用futimes
系统调用而不是utimes
系统调用。 换句话说:This tries to be a little more race-free than the other solutions. (The
with
keyword is new in Python 2.5.)Roughly equivalent to this.
Now, to really make it race-free, you need to use
futimes
and change the timestamp of the open filehandle, instead of opening the file and then changing the timestamp on the filename (which may have been renamed). Unfortunately, Python doesn't seem to provide a way to callfutimes
without going throughctypes
or similar...EDIT
As noted by Nate Parsons, Python 3.3 will add specifying a file descriptor (when
os.supports_fd
) to functions such asos.utime
, which will use thefutimes
syscall instead of theutimes
syscall under the hood. In other words:看起来这是 Python 3.4 的新功能 -
pathlib< /代码>
。
这将在路径中创建一个
file.txt
。--
Looks like this is new as of Python 3.4 -
pathlib
.This will create a
file.txt
at the path.--