使用Python实现触摸功能?

509

touch 是一种Unix实用程序,它将文件的修改和访问时间设置为当天的当前时间。如果该文件不存在,则会使用默认权限创建。

您如何将其实现为Python函数?请尝试跨平台并完整。

(当前搜索“python touch file”的 Google 结果并不理想,但指向 os.utime。)


7
考虑到此功能现在已经集成到Python标准库中,建议您更新已接受的答案。 - Miles
@Miles 接受的答案完全符合问题的要求 - 它实际上在Python中实现了该函数,而不是使用库。 - styrofoam fly
10
标准库是 Python 的一部分。很可能该问题的提问者(以及大多数通过谷歌搜索进入这个问题的人)真正想知道的是如何在他们的 Python 程序中实现类似于 touch 功能,而不是如何从头开始重新实现它。对于那些人来说,最好向下滚动到 pathlib 解决方案。尽管现在内置了此功能,但是这个答案在“python touch file”的谷歌排名上比相关文档更高。 - Miles
1
@miles Python 2仍然比3更广泛地使用,所以我认为被接受的答案仍然更相关。但是你的评论很好地指引了人们去看第二个答案。 - itsadok
9
Python 2 将于今年年底停止更新。 - Max Gasner
16个回答

2

复杂(可能存在缺陷):

def utime(fname, atime=None, mtime=None)
    if type(atime) is tuple:
        atime, mtime = atime

    if atime is None or mtime is None:
        statinfo = os.stat(fname)
        if atime is None:
            atime = statinfo.st_atime
        if mtime is None:
            mtime = statinfo.st_mtime

    os.utime(fname, (atime, mtime))


def touch(fname, atime=None, mtime=None):
    if type(atime) is tuple:
        atime, mtime = atime

    open(fname, 'a').close()
    utime(fname, atime, mtime)

此功能试图也允许设置访问或修改时间,就像GNU touch一样。


1

创建一个包含所需变量的字符串,并将其传递给os.system可能看起来很合乎逻辑:

touch = 'touch ' + dir + '/' + fileName
os.system(touch)

这种方法在很多方面都是不足的(例如,它不能处理空格),所以不要使用它。

更健壮的方法是使用 subprocess:

subprocess.call(['touch', os.path.join(dirname, fileName)])

虽然这比使用子 shell(os.system)要好得多,但仍只适用于快速脚本;对于跨平台程序,请使用被接受的答案。


这不是很安全的:如果文件名中有空格会发生什么? - ayke
5
subprocess.call(['touch', os.path.join(dirname, fileName)])比使用子Shell(使用os.system)要好得多。但是,仍然只在快速且粗略的脚本中使用它,在跨平台程序中请使用被接受的答案。 - ayke
1
“touch” 不是跨平台可用的命令(例如 Windows) - Mike T

1
可以使用pathlib.Path中的write_text()来完成。
>>> from pathlib import Path
>>> Path('aa.txt').write_text("")
0

touch 不会覆盖现有内容。 - Connor Clark
我不确定这是否是一个新功能,但Path也只是有一个触摸方法。 - undefined

0

我有一个用于备份的程序:https://stromberg.dnsalias.org/~strombrg/backshift/

我使用vmprof对其进行了分析,并确定touch是其中耗时最长的部分。

因此,我研究了快速触摸文件的方法。

我发现在CPython 3.11上,这是最快的方法:

def touch3(filename, flags=os.O_CREAT | os.O_RDWR):                                                                                  
    """Touch a file using os.open+os.close - fastest on CPython 3.11."""                                                             
    os.close(os.open(filename, flags, 0o644))    

                                                                                

在Pypy3 7.3.9上,这是最快的:

def touch1(filename):                                                                                                                
    """Touch a file using pathlib - fastest on pypy3, and fastest overall."""                                                        
    Path(filename).touch()                                                                                                           

在这两者之间,pypy3的最佳表现仅比cpython的最佳表现略快。

也许我将来会创建一个关于这个的网页,但现在我只有一个Subversion存储库: https://stromberg.dnsalias.org/svn/touch/trunk 它包括我尝试的4种触摸方式。


0

还有一个用于触摸的Python模块

>>> from touch import touch
>>> touch(file_name)

您可以使用 pip install touch 进行安装。

0
为什么不尝试: newfile.py
#!/usr/bin/env python
import sys
inputfile = sys.argv[1]

with open(inputfile, 'r+') as file:
    pass

Python新建文件.py foobar.txt

或者

使用子进程:

import subprocess
subprocess.call(["touch", "barfoo.txt"])

警告:上面的Python代码截断了文件。请使用“a”而不是“w”。 - bfontaine
1
@bfontaine,我刚刚修改了答案。它太危险了。 - Bachsau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接