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

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

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

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



답변

이것은 파이썬 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가 발생합니다.


답변

이것은 다른 솔루션보다 레이스를 조금 더 자유롭게하려고합니다. ( 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)


답변

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


답변

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

import os

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

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

여기서 가능한 경쟁 조건은 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())


답변

이 답변은 키워드 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)


답변

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