touch
是一个Unix实用程序,它将文件的修改和访问时间设置为当前时间.如果该文件不存在,则使用默认权限创建该文件.
你如何将它作为Python函数实现?尝试跨平台和完整.
(目前Google搜索"python touch file"的结果并不是那么好,但是指向os.utime.)
eph*_*ent 234
这试图比其他解决方案更无竞赛.(with
关键字是Python 2.5中的新增内容.)
import os
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
Run Code Online (Sandbox Code Playgroud)
大致相当于此.
import os
def touch(fname, times=None):
fhandle = open(fname, 'a')
try:
os.utime(fname, times)
finally:
fhandle.close()
Run Code Online (Sandbox Code Playgroud)
现在,要真正使其无竞争,您需要使用futimes
并更改打开文件句柄的时间戳,而不是打开文件,然后更改文件名(可能已重命名)的时间戳.不幸的是,Python似乎没有提供一种futimes
不经过ctypes
或类似的方式来打电话......
编辑
正如Nate Parsons所指出的,Python 3.3将添加 为函数指定文件描述符(何时os.supports_fd
)os.utime
,这将使用futimes
系统调用而不是utimes
系统调用.换一种说法:
import os
def touch(fname, mode=0o666, dir_fd=None, **kwargs):
flags = os.O_CREAT | os.O_APPEND
with os.fdopen(os.open(fname, flags=flags, mode=mode, dir_fd=dir_fd)) as f:
os.utime(f.fileno() if os.utime in os.supports_fd else fname,
dir_fd=None if os.supports_fd else dir_fd, **kwargs)
Run Code Online (Sandbox Code Playgroud)
voi*_*ogo 227
从Python 3.4开始看起来这是新的 - pathlib
.
from pathlib import Path
Path('path/to/file.txt').touch()
Run Code Online (Sandbox Code Playgroud)
这将file.txt
在路径上创建一个.
-
Path.touch(mode = 0o777,exist_ok = True)
在此给定路径创建文件.如果给出了mode,则将其与进程'umask值组合以确定文件模式和访问标志.如果文件已经存在,则如果exist_ok为true(并且其修改时间更新为当前时间),则函数成功,否则引发FileExistsError.
Sil*_*ost 41
def touch(fname):
if os.path.exists(fname):
os.utime(fname, None)
else:
open(fname, 'a').close()
Run Code Online (Sandbox Code Playgroud)
jco*_*and 26
为什么不尝试这个?:
import os
def touch(fname):
try:
os.utime(fname, None)
except OSError:
open(fname, 'a').close()
Run Code Online (Sandbox Code Playgroud)
我相信这可以消除任何重要的竞争条件.如果文件不存在,则抛出异常.
这里唯一可能的竞争条件是文件是在调用open()之前创建的,而是在os.utime()之后创建的.但这并不重要,因为在这种情况下,修改时间将如预期的那样,因为它必须在调用touch()期间发生.
这里有一些使用ctypes的代码(仅在Linux上测试过):
from ctypes import *
libc = CDLL("libc.so.6")
# struct timespec {
# time_t tv_sec; /* seconds */
# long tv_nsec; /* nanoseconds */
# };
# int futimens(int fd, const struct timespec times[2]);
class c_timespec(Structure):
_fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]
class c_utimbuf(Structure):
_fields_ = [('atime', c_timespec), ('mtime', c_timespec)]
utimens = CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))
futimens = CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))
# from /usr/include/i386-linux-gnu/bits/stat.h
UTIME_NOW = ((1l << 30) - 1l)
UTIME_OMIT = ((1l << 30) - 2l)
now = c_timespec(0,UTIME_NOW)
omit = c_timespec(0,UTIME_OMIT)
# wrappers
def update_atime(fileno):
assert(isinstance(fileno, int))
libc.futimens(fileno, byref(c_utimbuf(now, omit)))
def update_mtime(fileno):
assert(isinstance(fileno, int))
libc.futimens(fileno, byref(c_utimbuf(omit, now)))
# usage example:
#
# f = open("/tmp/test")
# update_mtime(f.fileno())
Run Code Online (Sandbox Code Playgroud)
对于更底层的解决方案,可以使用
os.close(os.open("file.txt", os.O_CREAT))
Run Code Online (Sandbox Code Playgroud)
自从发布Python-2.5关键字以来,此答案与所有版本兼容with
。
1.如果不存在则创建文件+设置当前时间
(与command完全相同touch
)
import os
fname = 'directory/filename.txt'
with open(fname, 'a'): # Create file if does not exist
os.utime(fname, None) # Set access/modified times to now
# May raise OSError if file does not exist
Run Code Online (Sandbox Code Playgroud)
一个更强大的版本:
import os
with open(fname, 'a'):
try: # Whatever if file was already existing
os.utime(fname, None) # => Set current time anyway
except OSError:
pass # File deleted between open() and os.utime() calls
Run Code Online (Sandbox Code Playgroud)
2.如果不存在,则仅创建文件
(不更新时间)
with open(fname, 'a'): # Create file if does not exist
pass
Run Code Online (Sandbox Code Playgroud)
3.只需更新文件访问/修改时间
(如果不存在则不创建文件)
import os
try:
os.utime(fname, None) # Set access/modified times to now
except OSError:
pass # File does not exist (or no permission)
Run Code Online (Sandbox Code Playgroud)
使用os.path.exists()
不会简化代码:
from __future__ import (absolute_import, division, print_function)
import os
if os.path.exists(fname):
try:
os.utime(fname, None) # Set access/modified times to now
except OSError:
pass # File deleted between exists() and utime() calls
# (or no permission)
Run Code Online (Sandbox Code Playgroud)
奖励:目录中所有文件的更新时间
from __future__ import (absolute_import, division, print_function)
import os
number_of_files = 0
# Current directory which is "walked through"
# | Directories in root
# | | Files in root Working directory
# | | | |
for root, _, filenames in os.walk('.'):
for fname in filenames:
pathname = os.path.join(root, fname)
try:
os.utime(pathname, None) # Set access/modified times to now
number_of_files += 1
except OSError as why:
print('Cannot change time of %r because %r', pathname, why)
print('Changed time of %i files', number_of_files)
Run Code Online (Sandbox Code Playgroud)
简单:
def touch(fname):
open(fname, 'a').close()
os.utime(fname, None)
Run Code Online (Sandbox Code Playgroud)
open
确保有一个文件存在utime
该时间戳更新,确保从理论上讲,有人可能会在 之后删除文件open
,从而导致 utime 引发异常。但可以说这没关系,因为确实发生了一些不好的事情。
归档时间: |
|
查看次数: |
162541 次 |
最近记录: |