Python创建空文件 - Unix

时间:2015-01-22 04:27:21

标签: python subprocess

我想在Unix环境中使用Python脚本创建空文件。可以看到提到实现相同的不同方式。一个人比另一个人有什么好处/陷阱。

os.system('touch abc')

open('abc','a').close()

open('abc','a')

subprocess.call(['touch','abc'])

4 个答案:

答案 0 :(得分:6)

嗯,首先,依赖touch的那些可移植。他们不会在标准Windows下工作,例如,没有安装CygWin,GNUWin32或其他提供touch实用程序的软件包。

他们还涉及创建一个单独的工作流程,在这种情况下完全没有必要。

在这四个中,我可能会使用open('abc','a').close(),如果意图是尝试只是创建文件,如果它不存在。在我的意见中,使意图明确。

但是,如果您尝试创建文件,我可能会使用w写入模式而不是a追加模式。

此外,您可能还希望捕获异常,例如,如果您无法实际创建该文件。

答案 1 :(得分:6)

TLDR:使用

open('abc','a').close()

(或'w'而不是'a'如果意图是截断文件(如果已存在)。

调用一个单独的进程来执行Python可以自己做的事情是浪费的,并且不可移植到外部命令不可用的平台。 (另外,os.system使用两个进程 - 一个用于解析命令行的shell - 并且被弃用而不是subprocess。)

当你完成它时没有关闭一个打开的文件句柄是不好的做法,并且可能导致更大的程序中的资源耗尽(如果你打开越来越多的文件并且从不关闭它们,你就会用完文件句柄)。 / p>

答案 2 :(得分:2)

在Python上用Unix创建一个空文件:

import os

try:
    os.close(os.open('abc', os.O_WRONLY | os.O_CREAT | os.O_EXCL | 
                     getattr(os, "O_CLOEXEC", 0) |
                     os.O_NONBLOCK | os.O_NOCTTY))
except OSError:
    pass # decide what to consider an error in your case and reraise
    # 1. is it an error if 'abc' entry already exists?
    # 2. is it an error if 'abc' is a directory or a symlink to a directory?
    # 3. is it an error if 'abc' is a named pipe?
    # 4. it is probably an error if the parent directory is not writable 
    #    or the filesystem is read-only (can't create a file)

或更便携的变体:

try:
    open('abc', 'ab', 0).close()
except OSError:
    pass # see the comment above

如果没有明确的.close()调用,非引用计数Python实现(如Pypy,Jython)可能会延迟关闭文件,直到运行垃圾收集(它可能会耗尽您的进程的可用文件描述符)。

后一个例子可能会停留在FIFO上并遵循符号链接。在我的系统上,它相当于:

from os import *
open("abc", O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, 0666)

此外,touch命令将现有文件的访问和修改时间更新为当前时间。

答案 3 :(得分:0)

在最新的Python 3变体中,我们从pathlib中提取了SELECT cust.[customerkey], COUNT(cust.[customerkey]) FROM [database1].[dbo].[customer] cust LEFT JOIN [database2].[mail].[emailsent] eml ON eml.[accountid] = cust.[accountid] WHERE eml.[accountid] IS NULL Group By cust.[customerkey] 。如果不存在,这将创建一个空文件,如果存在,将更新它的mtime,其方式与示例Path.touch()相同,但更加可移植:

os.system('touch abc')