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

如何将其实现为Python函数?尽量跨平台和完整。

(目前谷歌的“python触摸文件”的结果不是很好,但指向os.utime。)


当前回答

当关键字with已经发布时,此答案与Python-2.5以来的所有版本兼容。

1. 如果不存在则创建文件+设置当前时间 (与命令触摸完全相同)

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

一个更健壮的版本:

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

2. 如果文件不存在,则创建该文件 (不更新时间)

with open(fname, 'a'):  # Create file if does not exist
    pass

3.只需更新文件访问/修改次数 (如果不存在,则不创建文件)

import os

try:
    os.utime(fname, None)  # Set access/modified times to now
except OSError:
    pass  # File does not exist (or no permission)

使用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)

奖励:更新目录中所有文件的时间

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)

其他回答

当关键字with已经发布时,此答案与Python-2.5以来的所有版本兼容。

1. 如果不存在则创建文件+设置当前时间 (与命令触摸完全相同)

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

一个更健壮的版本:

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

2. 如果文件不存在,则创建该文件 (不更新时间)

with open(fname, 'a'):  # Create file if does not exist
    pass

3.只需更新文件访问/修改次数 (如果不存在,则不创建文件)

import os

try:
    os.utime(fname, None)  # Set access/modified times to now
except OSError:
    pass  # File does not exist (or no permission)

使用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)

奖励:更新目录中所有文件的时间

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)
def touch(fname):
    if os.path.exists(fname):
        os.utime(fname, None)
    else:
        open(fname, 'a').close()

简单的:

def touch(fname):
    open(fname, 'a').close()
    os.utime(fname, None)

打开确保那里有一个文件 utime确保时间戳被更新

从理论上讲,可能有人会在打开文件后删除该文件,导致utime引发异常。但可以说这没什么,因为坏事确实发生了。

复杂(可能有bug):

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。

with open(file_name,'a') as f: 
    pass