2012-01-05 46 views
11

Tôi cần cập nhật tệp. Tôi đọc nó và viết nó ra với những thay đổi. Tuy nhiên, tôi muốn viết vào một tập tin tạm thời và đổi tên nó thành vị trí.Trong python, tạo một tempfile trong cùng thư mục với một tệp khác?

temp = tempfile.NamedTemporaryFile() 
tempname = temp.name 
temp.write(new_data) 
temp.close() 
os.rename(tempname, data_file_name) 

Vấn đề là tempfile.NamedTemporaryFile() tạo tệp tạm thời trong /tmp là hệ thống tệp khác. Điều này có nghĩa là os.rename() không thành công. Nếu tôi sử dụng shlib.move() thay vào đó thì tôi không có bản cập nhật nguyên tử "mv" cung cấp (cho các tệp trong cùng hệ thống tệp, yadda, yadda, v.v.)

Tôi biết tempfile.NamedTemporaryFile() có thông số "dir", nhưng data_file_name có thể là "foo.txt" trong trường hợp dir = '.'; hoặc data_file_name có thể là "/path/to/the/data/foo.txt" trong trường hợp đó dir = "/path/to/the/data".

Điều tôi thực sự muốn là tệp tạm thời là data_file_name + "một số dữ liệu ngẫu nhiên". Điều này sẽ có lợi ích của thất bại trong một cách mà sẽ để lại đằng sau những manh mối hữu ích.

Đề xuất?

+3

Tại sao bạn sử dụng tệp tạm thời ở địa điểm đầu tiên, nếu bạn không muốn tệp đó được đặt trong thư mục cho tệp tạm thời? Những gì nói chống lại bằng cách sử dụng các tập tin bình thường? –

+1

David: Tôi muốn sử dụng một tập tin tạm thời bởi vì tôi muốn cập nhật là nguyên tử (hoặc là nguyên tử như một có thể được với os.rename()). Tức là, nếu hệ thống tệp đầy hoặc có một số vấn đề khác, tôi không muốn tệp được viết một nửa. – TomOnTime

+0

Vâng, điều này có thể khó đạt được, vì bạn không bao giờ thực sự biết, nếu các tệp được ghi vào một thư mục khác nằm trên cùng một hệ thống tệp làm thư mục cục bộ của bạn. Tôi thấy lợi thế của việc tổ chức đầu ra của bạn trong một số loại cam kết. Để tương đối chắc chắn rằng đây là trường hợp, tôi có lẽ sẽ quản lý thư mục tạm thời của riêng tôi - mặc dù bạn sẽ chăm sóc cho việc dọn dẹp thư mục này. –

Trả lời

17

Bạn có thể sử dụng:

  • prefix để làm cho các tập tin tạm thời bắt đầu với tên giống như file gốc.
  • dir để chỉ định vị trí đặt tệp tạm thời.
  • os.path.split để chia thư mục khỏi tên tệp.

import tempfile 
import os 
dirname, basename = os.path.split(filename) 
temp = tempfile.NamedTemporaryFile(prefix=basename, dir=dirname) 
print(temp.name) 
+0

Nếu filename = 'foo' thì tên dirname sẽ là ''. Tôi ngạc nhiên rằng NamedTemporaryFile làm việc với dir = '' giống như dir = None. Cảm ơn! – TomOnTime

+0

Chỉ để làm điều này rõ ràng: Bạn cũng phải vượt qua 'xóa = False' để xây dựng NamedTemporaryFile, hoặc tập tin sẽ bị xóa khi đóng. – moeffju

2

tôi sử dụng thời gian hiện tại là "một số dữ liệu ngẫu nhiên" nối vào một chuỗi cơ sở cho một tên tập tin tạm thời duy nhất:

import time 

temp_file_name = data_file_name + str(time.time()) 
+0

Điều này là hấp dẫn, nhưng tôi đã nhìn thấy đủ vấn đề an ninh từ những người lăn hệ thống tệp tạm thời của riêng họ mà tôi biết để sử dụng một tempfile cung cấp. – TomOnTime

+0

Giống như một lưu ý bổ sung ở đây, một vài năm sau, điều này sẽ có xung đột nếu điều này chạy hai lần trong cùng một phần nghìn giây, điều này chắc chắn có thể xảy ra trong hầu hết các trường hợp sử dụng của mọi người. Nó tốt hơn chỉ để sử dụng thực hiện chính thức của tempfile, để các công cụ như thế, và điều kiện chủng tộc khi bạn cố gắng tránh nó. – daboross

4

Bạn có thể vượt qua một vị trí tập tin trong tham số constructor 'dir'. Nó hoạt động, như bạn muốn.

>>> t = tempfile.NamedTemporaryFile(dir="/Users/rafal") 
>>> t.name 
'/Users/rafal/tmplo45Js' 

Nguồn: http://docs.python.org/library/tempfile.html#tempfile.NamedTemporaryFile

+2

thông tin: không có 'xóa = False' tệp sẽ bị xóa ngay sau khi trình xử lý tệp bị đóng. – gecco

+0

Điều này giả định chúng ta biết dir là gì. – TomOnTime

+0

Chúng tôi biết điều đó. Câu hỏi đã có của OP có chứa một đường dẫn vào dir và tên tệp, do đó, nó không cần thiết để viết về nó ở đây. –

4

Để đáp ứng tất cả các danh sách kiểm tra của bạn tôi nghĩ rằng bạn muốn sử dụng ...

temp = tempfile.NamedTemporaryFile(prefix=data_file_name, dir=path, 
            delete=False) 

quan trọng để có delete=False, bởi vì nếu không:

[...] Nếu xóa là đúng (mặc định), tệp sẽ bị xóa ngay sau khi được đóng .

+0

Điều này giả định chúng ta biết con đường là gì. – TomOnTime

-1

Mô-đun tempfile mà bạn sử dụng cung cấp cách quản lý tệp tạm thời an toàn. Nếu bạn thực sự muốn sử dụng hệ thống của riêng mình, bạn nên lưu ý rằng nó có thể dễ bị tấn công (đặc biệt là các cuộc tấn công của symlink).

Một cách đơn giản để tạo ra một tên tập tin độc đáo tạm thời (mặc dù một tên khá dài) là:

import uuid 
import os 

tempfilename = 'myprefix-%s.dat' % str(uuid.uuid4()) 

with open(tempfilename, 'rw') as tempfile: 
    # do stuff 

os.remove(tempfilename) 

Nhưng đây là một chút hackish; thực sự thay vì xem xét sử dụng mô-đun tempfile với các thông số prefixdir chính xác được chuyển đến NamedTemporaryFile, như được mô tả trong các câu trả lời khác.

+0

Điều này là hấp dẫn, nhưng tôi đã nhìn thấy đủ vấn đề an ninh gây ra bởi những người lăn hệ thống tập tin tạm thời của riêng họ mà tôi biết để sử dụng một tempfile cung cấp. – TomOnTime

+0

Tuyệt đối, sử dụng một cái gì đó như thế này là một ý tưởng tồi trong mã sản xuất. Trong một môi trường mà đây không phải là mối quan tâm (ví dụ: ghi nhật ký dữ liệu mô phỏng), 'uuid' trình bày cách tạo một chuỗi ngẫu nhiên duy nhất. –

Các vấn đề liên quan