2014-10-24 3 views
38

में वास्तविक फ़ाइल बनाने के बिना अस्थायी फ़ाइल नाम जेनरेट करें प्रश्न, number 10501247, स्टैक ओवरफ्लो में, पाइथन में अस्थायी फ़ाइल बनाने का उत्तर देता है।
मुझे केवल मेरे मामले में अस्थायी फ़ाइल नाम होना चाहिए।
कॉलिंग tempfile.NamedTemporaryFile() वास्तविक फ़ाइल निर्माण के बाद फ़ाइल हैंडल देता है।
क्या फ़ाइल नाम केवल पाने का कोई तरीका है?पाइथन

# Trying to get temp file path 
tf = tempfile.NamedTemporaryFile() 
temp_file_name = tf.name 
tf.close() 
# Here is my real purpose to get the temp_file_name 
f = gzip.open(temp_file_name ,'wb') 
... 
+4

'नामांकित समकालीन फ़ाइल 'एक अद्वितीय नाम की गारंटी देता है, (शायद) इसे आजमाकर और यदि यह मौजूद है तो पुनः प्रयास कर रहा है। सिर्फ एक नाम प्राप्त करने से यह गारंटी नहीं मिलेगी कि आप वास्तव में बाद में फ़ाइल बना सकते हैं, आप किसी भी अन्य नाम की दौड़ स्थिति को आपके सामने एक ही नाम का उपयोग कर खोल रहे हैं। –

+2

@ जोचिम ट्रू, यहां एक दौड़ की स्थिति है और इसे टालना पसंद किया जाएगा। हालांकि, कभी-कभी आपको एक फ़ंक्शन में एक अस्थायी फ़ाइल नाम पारित करना होता है (फ़ाइल को आंतरिक रूप से हो रहा है।) अच्छी तरह से यादृच्छिक नाम होने से एक बेहतर संभावना है कि दौड़ की स्थिति एक गैर-समस्या होगी। मुझे लगता है कि दौड़ की स्थिति विफलता के मौके को कम करने के लिए एक अच्छा अस्थायी फ़ाइल नाम प्रदान करने की वैध आवश्यकता है। निश्चित रूप से चल रही प्रक्रिया और कार्य के आधार पर एक अच्छा उपसर्ग और प्रत्यय जोड़ना टकराव का भी कम मौका प्रदान करेगा। – PolyMesh

उत्तर

30

आप एक अस्थायी फ़ाइल नाम चाहते हैं केवल आप भीतरी tempfile समारोह _get_candidate_names() कॉल कर सकते हैं:,

import tempfile 

temp_name = next(tempfile._get_candidate_names()) 
% e.g. px9cp65s 

फिर next कॉलिंग एक और नाम वापस आ जाएगी, आदि यह आपको अस्थायी करने के लिए पथ नहीं देता फ़ोल्डर। डिफ़ॉल्ट 'tmp' निर्देशिका पाने के लिए, का उपयोग करें:

defult_tmp_dir = tempfile._get_default_tempdir() 
% results in: /tmp 
+2

एक temp निर्देशिका बनाने के लिए बेहतर तरीका 'temp_dir = tempfile है।mkdtemp (prefix = 'some-prefix _') 'जो सुरक्षित रूप से अस्थायी निर्देशिका बनाएगा और पूर्ण पथ के साथ एक स्ट्रिंग वापस करेगा। –

4

जोआचिम Isaksson के रूप में टिप्पणी में कहा, आप समस्या हो सकती है किसी अन्य प्रोग्राम से पहले अपने कार्यक्रम करता है कि नाम का उपयोग करने के लिए होता है, तो अगर आप सिर्फ एक नाम मिलता है। संभावनाएं पतली हैं, लेकिन असंभव नहीं हैं।

इसलिए इस स्थिति में करने के लिए सुरक्षित चीज पूर्ण GzipFile() कन्स्ट्रक्टर का उपयोग करना है, जिसमें हस्ताक्षर GzipFile([filename[, mode[, compresslevel[, fileobj]]]]) है। तो यदि आप चाहें तो आप इसे खुले फ़ाइलबोज और एक फ़ाइल नाम भी पास कर सकते हैं। विवरण के लिए gzip दस्तावेज़ देखें।

10

यह थोड़ा देर हो सकता है, लेकिन क्या इसमें कुछ गड़बड़ है?

import tempfile 
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as tmpfile: 
    temp_file_name = tmpfile.name 
f = gzip.open(temp_file_name ,'wb') 
+11

यह कोड वास्तव में अपना नाम प्राप्त करने के लिए अस्थायी फ़ाइल बनाएगा, जबकि प्रश्न में यह 'पायथन में वास्तविक फ़ाइल बनाने के बिना' कहता है। – jkukul

+0

यह – herve

6

tempfile.mktemp() यह करते हैं।

लेकिन ध्यान दें कि यह बहिष्कृत है। हालांकि यह नहीं फ़ाइल बनायेगा और यह _get_candidate_names() का उपयोग करने की तुलना में tempfile में एक सार्वजनिक कार्य है।

इसे छोड़ने का कारण यह है कि इसे कॉल करने और वास्तव में फ़ाइल बनाने की कोशिश करने के बीच के समय के अंतर के कारण है। हालांकि मेरे मामले में इसका मौका इतना पतला है और यहां तक ​​कि अगर यह असफल हो जाता है तो यह स्वीकार्य होगा। लेकिन यह आपके उपयोग के लिए मूल्यांकन करने के लिए आप पर निर्भर है।

+1

प्रश्न का उत्तर नहीं देता है "भले ही यह विफल हो जाए जो स्वीकार्य होगा"; दौड़ की स्थिति केवल विफलता का जोखिम नहीं है, यह एक सुरक्षा जोखिम है ('tempfile.mktemp' दस्तावेज देखें)। तो इसे स्वीकार्य नहीं माना जाना चाहिए। – bignose

+2

@ बिग्नोज़ यह एक * संभावित * सुरक्षा समस्या है। यह इस बात पर निर्भर करता है कि आप क्या करना चाहते हैं, निष्पादन वातावरण, जिसमें आप हैं, आदि ने कहा: यह os.path.join (tempfile.mkdtemp(), 'something') जैसे कुछ करने के लिए और अधिक सुरक्षित हो सकता है। कम से कम निर्देशिका बनाई गई है (और आपके स्वामित्व में, मुझे लगता है)। – Alec

7

मुझे लगता है कि सबसे आसान, ऐसा करने का सबसे सुरक्षित तरीका है कुछ की तरह:

path = os.path.join(tempfile.mkdtemp(), 'something') 

एक अस्थायी निर्देशिका कि केवल आप उपयोग कर सकते हैं, इसलिए कोई सुरक्षा के मुद्दों होना चाहिए, लेकिन नहीं होगी बनाई गई है कोई इसमें बनाई गई फाइलें, ताकि आप उस निर्देशिका में कोई भी फ़ाइल नाम चुन सकें जिसे आप बनाना चाहते हैं।