2010-06-02 593 views
51

我有一个python web窗体有两个选项 - 文件上传textarea。我需要从每个值中取出值并将它们传递给另一个命令行程序。我可以很容易地通过文件上传选项的文件名,但我不知道如何传递textarea的值。Python:如何创建一个唯一的文件名?

我想我需要做的是:

  1. 生成一个唯一的文件名
  2. 创建工作目录
  3. 保存从文本区域传递到临时值与该名称的临时文件文件
  4. 从我的Python模块中执行命令行程序,并通过它的临时文件的名称

我不知道如何生成一个唯一的文件名。任何人都可以给我一些关于如何生成唯一文件名的提示吗?任何算法,建议和代码行赞赏。

谢谢你的关心

+1

我编辑你的问题,试图使之更加清晰。让我知道,如果我解释错误的东西! – culix 2012-09-01 10:12:53

回答

82

我不认为你的问题很清楚,但如果你需要的是一个唯一的文件名称...

import uuid 

unique_filename = str(uuid.uuid4()) 
+0

我是否应该以更理解的方式再次编辑我的问题? – MysticCodes 2010-06-02 21:26:42

+0

对不起,我在Windows平台上工作,所以不知道如何处理子流程 – MysticCodes 2010-06-03 10:04:00

+0

uuid似乎创建了一个很长的唯一字符串。我不认为它有更好的文件名与长字符串和UUID,()在它。 – MysticCodes 2010-06-03 10:37:13

41

如果你想临时文件在Python中,Python的标准库中有一个名为tempfile的模块。如果要启动其他程序以对文件进行操作,请使用tempfile.mkstemp()创建文件,使用os.fdopen()访问mkstemp()为您提供的文件描述符。

顺便说一下,你说你正在运行Python程序中的命令?你应该几乎肯定会使用subprocess模块。

所以你可以很愉快地编写代码,看起来像:

import subprocess 
import tempfile 
import os 

(fd, filename) = tempfile.mkstemp() 
try: 
    tfile = os.fdopen(fd, "w") 
    tfile.write("Hello, world!\n") 
    tfile.close() 
    subprocess.Popen(["/bin/cat", filename]).wait()   
finally: 
    os.remove(filename) 

运行,你应该发现cat命令工作得很好,但临时文件是在finally块删除。请注意,您已将删除mkstemp()自动返回的临时文件 - 库无法知道您何时完成它! (编辑:我曾假设NamedTemporaryFile完成了你之后的工作,但那可能不是那么方便 - 当临时文件对象关闭时文件立即被删除,并让其他进程在你之前打开文件已关闭它将无法在某些平台上运行,特别是Windows。对不起,我的部分失败。)

+0

使用** NamedTemporaryFile **可能是他们想要的(除非他们希望它留在服务器上,然后他们可以使用“tempfile.NamedTemporaryFile(delete = False)”) – 2010-06-02 21:24:22

+0

我可以使该临时文件名称也是唯一的吗?所以我以后可以在子进程完成时使用唯一名称来保存它 – MysticCodes 2010-06-02 21:25:22

+0

@Terence Honles:我最初建议使用tempfile.NamedTemporaryFile(),但您无法真正使用它来创建其他进程可以在Windows上访问的临时文件。尽管如此,NamedTemporaryFile(delete = False)肯定是*更清晰的。 @ user343934:tempfile。mkstemp()在每次调用时都会给你一个唯一的名字 - 它随机生成名称,并使用操作系统工具(如果你想知道的话,可以使用O_EXCL)来避免冲突。 – 2010-06-02 21:33:45

2

我遇到了这个问题,我将为那些可能正在寻找类似东西的人添加我的解决方案。我的方法是从ascii个字符中随机创建一个文件名。这将是一个很好的概率独一无二的。

from random import sample 
from string import digits, ascii_uppercase, ascii_lowercase 
from tempfile import gettempdir 
from os import path 

def rand_fname(suffix, length=8): 
    chars = ascii_lowercase + ascii_uppercase + digits 

    fname = path.join(gettempdir(), 'tmp-' 
       + ''.join(sample(chars, length)) + suffix) 

    return fname if not path.exists(fname) \ 
       else rand_fname(suffix, length) 
+1

这个问题的明显答案与uuid包有关。但是,我的目标服务器有python 2.4,没有uuid包和升级未经服务器所有者授权,因为传统软件不兼容,所以这个答案适用于我。 – 2014-10-03 18:04:13

+1

我特别喜欢这个答案:可以很容易地调整项目规格。 – swdev 2015-04-29 02:41:33

+0

1)没有理由在这里使用递归,尤其是无界的。 2)'path.exists()'返回False时间与消费者实际打开文件的时间之间存在竞争条件。 – 2017-04-08 22:21:12

8

也许你需要独特的临时文件?

import tempfile 

f = tempfile.NamedTemporaryFile(mode='w+b', delete=False) 

print f.name 
f.close() 

f是打开的文件。 delete=False表示关闭后不要删除文件。

+0

如果您不需要控制文件的名称,这非常棒。 – hiwaylon 2014-10-28 18:34:13

+1

它应该是tmpfile.NamedTemporaryFile不只是NamedTemporaryFile。 – user1993015 2017-07-15 03:19:05

2

这可以使用独特的函数在ufp.path模块中完成。

import ufp.path 
ufp.path.unique('./test.ext') 

如果当前路径存在'test.ext'文件。 ufp.path.unique函数返回'./test(d1).ext'。

见例如: Generate unique path at filepath or dirpath [Python]

+2

ufp是drupal的一部分吗?不是标准模块 – endolith 2015-08-07 23:09:05

2

可以使用datetime模块

import datetime 
uniq_filename = str(datetime.datetime.now().date()) + '_' + str(datetime.datetime.now().time()).replace(':', '.') 

注: 我使用replace因为冒号不是在许多操作系统允许文件。

就是这样,每次只会给你一个唯一的文件名。

6

uuid模块将是一个不错的选择,我更喜欢使用uuid.uuid4().hex随机文件名,因为它会返回没有破折号一个十六进制字符串。

import uuid 
filename = uuid.uuid4().hex 

输出应该是这样的:

>>> import uuid 
>>> uuid.uuid() 
UUID('20818854-3564-415c-9edc-9262fbb54c82') 
>>> str(uuid.uuid4()) 
'f705a69a-8e98-442b-bd2e-9de010132dc4' 
>>> uuid.uuid4().hex 
'5ad02dfb08a04d889e3aa9545985e304' # <-- this one 
相关问题