파이썬을 사용하여 터치를 구현 하시겠습니까?


352

touch파일의 수정 및 액세스 시간을 현재 시간으로 설정하는 Unix 유틸리티입니다. 파일이 존재하지 않으면 기본 권한으로 파일이 작성됩니다.

파이썬 함수로 어떻게 구현하겠습니까? 크로스 플랫폼이되고 완성되도록 노력하십시오.

"python touch 파일"에 대한 현재 Google 결과는 그리 좋지 않지만 os.utime을 가리 킵니다 .


4
이 기능은 Python stdlib에 내장되어 있으므로 허용되는 답변을 업데이트하십시오.
Miles

@Miles 허용되는 답변은 질문에서 요청한 것과 정확히 일치합니다. 실제로 라이브러리를 사용하는 대신 Python에서 함수를 구현했습니다.
스티로폼

5
@styrofoamfly 표준 라이브러리 Python의 일부입니다. 질문자가 실제로 알고 싶어하는 것 (그리고 Google을 통해이 질문에 도달하는 대부분의 사람들)은 touch파이썬 프로그램에서 같은 기능 을 달성 하는 방법이 아니라 처음부터 다시 구현하는 방법이 아니라고 생각합니다. 그 사람들은 pathlib솔루션 으로 스크롤하여 가장 잘 제공됩니다 . 현재는 내장되어 있지만이 답변은 관련 문서 보다 "python touch 파일"에 대한 Google 순위가 훨씬 우수 합니다 .
Miles

@miles Python 2는 (아쉽게도) 3보다 여전히 널리 사용되므로 허용되는 답변이 여전히 더 관련성이 있다고 생각합니다. 그러나 귀하의 의견은 사람들에게 두 번째 답변을 가리키는 좋은 일을합니다.
itsadok

6
파이썬 2는 올해 말 EOL입니다.
Max Gasner 2018

답변:


304

이것은 파이썬 3.4-에서 새로운 것 같습니다 pathlib.

from pathlib import Path

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

file.txt경로에 가 생성됩니다 .

-

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

이 지정된 경로에 파일을 작성하십시오. mode가 지정되면 프로세스의 umask 값과 결합되어 파일 모드 및 액세스 플래그를 결정합니다. 파일이 이미 존재하면 exist_ok가 true이고 수정 시간이 현재 시간으로 업데이트되면 함수가 성공하고 그렇지 않으면 FileExistsError가 발생합니다.


3
Python2.7 :pip install pathlib
Andre Miras

8
자체 참고 사항 : ed Path('/some/path').mkdir()파일이 들어있는 디렉토리가 touch()아직없는 경우 사용 하십시오 .
JacobIRR

1
버그 수정 전용 이기 때문에 pathlib2대신 사용해야한다고 생각합니다 . 따라서 Python 2.7에서 다음을 수행하십시오 . pathlibpathlibpip install pathlib2from pathlib2 import Path
이안 린

@IanLin 표준 라이브러리가 이미 지원하는 것을 수행하기 위해 라이브러리를 설치할 이유가 거의 없습니다. bitbucket.org/pitrou/pathlib/src/defaultdocs.python.org/dev/library/pathlib.html 을 혼동 하고 있습니까 ?
Michael Mrozek

그 의견은 표준 라이브러리가없는 Python 2.7에 대해 이야기하는 Andre의 의견에 답하고 있습니다. pypi.org/project/pathlib2
Ian Lin

242

이것은 다른 솔루션보다 레이스를 조금 더 자유롭게하려고합니다. ( 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않고 호출하는 방법을 제공하지 않는 것 같습니다 ctypes...


편집하다

Nate Parsons가 지적한 것처럼 Python 3.3은 파일 디스크립터 지정 ( )을 ( 와 같은) 함수에 추가 하여 후드 아래의 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)

이것이 실제 솔루션이며 futimes ()를 사용할 수없는 경우가 아니라면 coreutils의 touch (1)가 수행하는 방식입니다. futimes는 이식 가능한 기능이 아니며 이전 2.6 Linux 커널에는 존재하지 않으므로 ENOSYS를 처리하고 사용하더라도 utime으로 대체해야합니다.
Glenn Maynard

(위의 교정 오류 : "This"= open ( "a") + futimes.) 다행히 Futimes를 사용하지 않는 경쟁 조건이 실제로 중요한 경우를 생각하기는 어렵습니다. 결국 "잘못된"경우는 open ()과 utime () 사이에서 이름이 바뀌는 파일입니다.이 경우 새 파일을 만들거나 이전 파일을 건드리지 않습니다. 문제가 될 수 있지만 대부분은 그렇지 않습니다.
Glenn Maynard

cygwin touch는 읽기 전용 파일에서 마법을 수행 할 수 있지만이 코드는 불가능합니다. 그러나 try : <code>로 둘러싸면 IOError를 제외하고 e : (e.errno를 확인하십시오) os.utime (filename, times)
dash-tom-bang

참고로, futimes가 3.3에 추가 된 것 같습니다
Nate Parsons

참고 : 내장 file함수는 Python 3에서 제거되었으며 open대신 사용해야합니다. 내가 사용하고있는 편집기 (gedit)의 구문 강조가 여전히 파이썬 2를 목표로하고 있기 때문에 나는 이것을 완전히 놓쳤다.
Bart

42
def touch(fname):
    if os.path.exists(fname):
        os.utime(fname, None)
    else:
        open(fname, 'a').close()

24
이 솔루션에는 잠재적 인 경쟁 조건이 있습니다. 파일이 존재하지 않고이 함수가 open()호출에 도달하기 전에 다른 프로세스에 의해 작성 되면 파일의 내용이 잘립니다. 'a'대신 모드 사용을 제안하십시오 .
그렉 Hewgill

7
동의했다. 적절한 해결책은 다음과 같습니다. def touch (fname) : open (fname, 'wa'). close ()
stepancheg

@Greg는 잠재적 인 경주 조건 문제를 해결하지만 open(fname, 'a').close()시간이 바뀌지 않습니다.
SilentGhost

@SilentGhost : 그건 사실이지만, 파일이 존재하는 경우가 있었기 때문에 괜찮아요 단지 만들었습니다. 물론 os.utime()기존 파일에 대한 호출을 남겨 두어야 합니다.
그렉 Hewgill

4
열려 있는지 확인한 다음 utime에 전화하십시오.
itsadok

31

왜 이것을 시도하지 않습니까? :

import os

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

나는 이것이 중요한 경쟁 조건을 제거한다고 생각합니다. 파일이 존재하지 않으면 예외가 발생합니다.

여기서 가능한 경쟁 조건은 open ()을 호출하기 전에 os.utime () 이후에 파일을 만드는 경우입니다. 그러나이 경우 수정 시간이 touch () 호출 중에 발생했기 때문에 수정 시간이 예상대로되기 때문에 중요하지 않습니다.


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())

8

이 답변은 키워드 with가 릴리스 되었을 때 Python-2.5부터 모든 버전과 호환됩니다 .

1. 존재하지 않는 경우 파일 작성 + 현재 시간 설정
(정확히 명령과 동일 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

보다 강력한 버전 :

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)

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

실패 : with open(fn,'a'): pass또는 대안 open(fn, 'a').close()은 Red Hat 7에서 Python 2.7.5를 사용하여 수정 된 시간을 변경하지 않습니다 (파일 시스템은 XFS 임). 내 플랫폼에서 이러한 솔루션은 존재하지 않는 경우 빈 파일을 만듭니다. :-/
olibre

3

단순함 :

def touch(fname):
    open(fname, 'a').close()
    os.utime(fname, None)
  • open보장하는 파일이 존재
  • utime타임 스탬프가 업데이트 보장해

이론적으로 누군가가 파일 다음에 파일을 삭제 open하여 utime에서 예외가 발생할 수 있습니다. 그러나 나쁜 일이 일어났기 때문에 괜찮습니다.


1

복잡함 (아마도 버그가 있음) :

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.call(['touch', os.path.join(dirname, fileName)])

이것은 os.system과 함께 서브 쉘을 사용하는 것보다 훨씬 낫지 만 여전히 빠르고 더러워진 스크립트에만 적합합니다. 크로스 플랫폼 프로그램에 허용되는 답변을 사용하십시오.


이것은 안전하지 않습니다. 파일 이름에 공백이 있으면 어떻게됩니까?
ayke

5
subprocess.call(['touch', os.path.join(dirname, fileName)])서브 쉘 (with os.system)을 사용하는 것보다 훨씬 낫습니다 . 그러나 여전히 빠르고 더러운 스크립트에만 이것을 사용하고 크로스 플랫폼 프로그램에 허용되는 대답을 사용하십시오.
ayke

1
touch크로스 플랫폼에서 사용 가능한 명령이 아닙니다 (예 : Windows)
Mike T

1

"open (file_name, 'a'). close ()"는 Windows의 Python 2.7에서 작동하지 않습니다. "os.utime (file_name, None)"은 정상적으로 작동했습니다.

또한 디렉토리의 모든 파일을 날짜보다 오래된 날짜로 재귀 적으로 터치해야했습니다. 나는 ephemient의 매우 유용한 답변을 바탕으로 다음과 같은 것들을 만들었습니다.

def touch(file_name):
    # Update the modified timestamp of a file to now.
    if not os.path.exists(file_name):
        return
    try:
        os.utime(file_name, None)
    except Exception:
        open(file_name, 'a').close()

def midas_touch(root_path, older_than=dt.now(), pattern='**', recursive=False):
    '''
    midas_touch updates the modified timestamp of a file or files in a 
                directory (folder)

    Arguements:
        root_path (str): file name or folder name of file-like object to touch
        older_than (datetime): only touch files with datetime older than this 
                   datetime
        pattern (str): filter files with this pattern (ignored if root_path is
                a single file)
        recursive (boolean): search sub-diretories (ignored if root_path is a 
                  single file)
    '''
    # if root_path NOT exist, exit
    if not os.path.exists(root_path):
        return
    # if root_path DOES exist, continue.
    else:
        # if root_path is a directory, touch all files in root_path
        if os.path.isdir(root_path):
            # get a directory list (list of files in directory)
            dir_list=find_files(root_path, pattern='**', recursive=False)
            # loop through list of files
            for f in dir_list:
                # if the file modified date is older thatn older_than, touch the file
                if dt.fromtimestamp(os.path.getmtime(f)) < older_than:
                    touch(f)
                    print "Touched ", f
        # if root_path is a file, touch the file
        else:
            # if the file modified date is older thatn older_than, touch the file
            if dt.fromtimestamp(os.path.getmtime(f)) < older_than:
                touch(root_path)

1

왜 안 해봐 : 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"])

0

다음은 충분합니다.

import os
def func(filename):
    if os.path.exists(filename):
        os.utime(filename)
    else:
        with open(filename,'a') as f:
            pass

터치 할 특정 시간을 설정하려면 다음과 같이 os.utime을 사용하십시오.

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

여기서 atime과 mtime은 모두 int / float이어야하며 설정하려는 시간과 초 단위의 에포크 시간과 같아야합니다.


0

시도 제외를 신경 쓰지 않으면 ...

def touch_dir(folder_path):
    try:
        os.mkdir(folder_path)
    except FileExistsError:
        pass

그러나 한 가지 주목할 점은, 파일이 같은 이름으로 존재하면 작동하지 않으며 자동으로 실패합니다.


0

write_text()에서 pathlib.Path사용할 수 있습니다.

>>> from pathlib import Path
>>> Path('aa.txt').write_text("")
0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.