442

touchファイルの変更時刻とアクセス時刻を現在の時刻に設定する Unix ユーティリティです。ファイルが存在しない場合は、既定のアクセス許可で作成されます。

Python 関数としてどのように実装しますか? クロスプラットフォームで完全であるようにしてください。

(「python touch file」に対する現在の Google の結果はそれほど素晴らしいものではありませんが、os.utimeを指しています。)

4

15 に答える 15

451

これは Python 3.4 の時点で新しいようですpathlib

from pathlib import Path

Path('path/to/file.txt').touch()

これにより、パスに が作成file.txtされます。

--

Path.touch(mode=0o777, exist_ok=True)

この指定されたパスにファイルを作成します。mode を指定すると、プロセスの umask 値と組み合わされて、ファイル モードとアクセス フラグが決定されます。ファイルが既に存在する場合、exist_ok が true (およびその変更時刻が現在の時刻に更新される) の場合、関数は成功します。それ以外の場合は、FileExistsError が発生します。

于 2016-01-05T03:45:06.120 に答える
251

これは、他のソリューションよりも少しレースフリーにしようとします。(withキーワードはPython 2.5の新機能です。)

import os
def touch(fname, times=None):
    with open(fname, 'a'):
        os.utime(fname, times)

これとほぼ同等です。

import os
def touch(fname, times=None):
    fhandle = open(fname, 'a')
    try:
        os.utime(fname, times)
    finally:
        fhandle.close()

さて、本当にレースフリーにするにfutimesは、ファイルを開いてからファイル名のタイムスタンプを変更するのではなく、開いているファイルハンドルのタイムスタンプを使用して変更する必要があります(名前が変更されている可能性があります)。futimes残念ながら、Pythonは、通過することなく、または同様の方法で呼び出す方法を提供していないようですctypes...


編集

Nate Parsonsが指摘しているように、Python 3.3は、ファイル記述子の指定(when )をなどの関数に追加 します。この関数は、内部でsyscallの代わりにsyscallを使用します。言い換えると:os.supports_fdos.utimefutimesutimes

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)
于 2009-07-21T16:17:59.703 に答える
45
def touch(fname):
    if os.path.exists(fname):
        os.utime(fname, None)
    else:
        open(fname, 'a').close()
于 2009-07-21T09:11:18.593 に答える
35

これを試してみませんか?:

import os

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

これにより、重要な競合状態が解消されると思います。ファイルが存在しない場合は、例外がスローされます。

ここで考えられる唯一の競合状態は、open() が呼び出される前にファイルが作成されたが、os.utime() の後に作成された場合です。しかし、これは重要ではありません。なぜなら、この場合、修正時間は、touch() の呼び出し中に発生したに違いないため、予想どおりになるからです。

于 2011-06-03T03:31:28.337 に答える
10

より低レベルのソリューションについては、使用できます

os.close(os.open("file.txt", os.O_CREAT))
于 2020-08-26T19:48:21.670 に答える
8

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())
于 2012-01-14T07:44:18.393 に答える
6

単純化:

def touch(fname):
    open(fname, 'a').close()
    os.utime(fname, None)
  • そこopenにファイルがあることを確認します
  • これutimeにより、タイムスタンプが確実に更新されます

理論的には、誰かが の後にファイルを削除し、openutime で例外が発生する可能性があります。しかし、何か悪いことが起こったので、間違いなくそれは問題ありません。

于 2009-07-21T10:30:54.250 に答える
4
with open(file_name,'a') as f: 
    pass
于 2015-11-07T00:20:57.703 に答える
1

目的の変数で文字列を作成し、それを os.system に渡すのは理にかなっているように思えるかもしれません。

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

これは多くの点で不適切なので (たとえば、空白を処理しない)、使用しないでください。

より堅牢な方法は、 subprocess を使用することです:

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

これは、サブシェル (os.system を使用) を使用するよりもはるかに優れていますが、依然として、迅速かつダーティなスクリプトにしか適していません。クロスプラットフォーム プログラムに受け入れられた回答を使用します。

于 2012-06-28T16:49:38.970 に答える
0

試してみませんか: newfile.py

#!/usr/bin/env python
import sys
inputfile = sys.argv[1]

with open(inputfile, 'w') as file:
    pass

python newfile.py foobar.txt

また

サブプロセスを使用:

import subprocess
subprocess.call(["touch", "barfoo.txt"])
于 2019-09-04T17:12:34.553 に答える