পাইথনে আসল ফাইল না তৈরি করে অস্থায়ী ফাইলের নাম তৈরি করুন


105

প্রশ্ন, স্ট্যাকওভারফ্লোতে 10501247 সংখ্যাটি পাইথনে অস্থায়ী ফাইল কীভাবে তৈরি করবেন তার উত্তর দেয়।
আমার ক্ষেত্রে কেবলমাত্র অস্থায়ী ফাইলের নাম থাকা দরকার।
টেম্পাইল ফাইল করা.নামডেম্পের্পিয়ারফিল () প্রকৃত ফাইল তৈরির পরে ফাইল হ্যান্ডেল ফিরিয়ে দেয়।
কেবলমাত্র ফাইলের নাম পাওয়ার উপায় আছে?

# 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')
...

7
NamedTemporaryFileএকটি অনন্য নামের গ্যারান্টি দেয় (সম্ভবত) এটি চেষ্টা করে এবং এটি উপস্থিত থাকলে আবার চেষ্টা করে। কেবল একটি নাম পাওয়া গ্যারান্টি দেয় না যে আপনি আসলে ফাইলটি পরে তৈরি করতে পারবেন, আপনি নিজের আগে একই নাম ব্যবহার করে অন্য কারও দৌড়ের শর্তের দিকে যাচ্ছেন।
জোছিম ইসাকসন

5
@ জোয়াচিম সত্য, এখানে একটি দৌড়ের শর্ত রয়েছে এবং এটি এড়ানো পছন্দ করা উচিত। যাইহোক, কখনও কখনও আপনাকে কোনও ফাংশনে অস্থায়ী ফাইলের নামটি পাস করতে হয় (ফাইলটি অভ্যন্তরীণভাবে উন্মুক্ত হয়ে যায় a আমি মনে করি একটি রেস কন্ডিশনের ব্যর্থতার সম্ভাবনা হ্রাস করার জন্য একটি ভাল অস্থায়ী ফাইল নাম সরবরাহ করার একটি বৈধ প্রয়োজন আছে। অবশ্যই চলমান প্রক্রিয়া এবং কার্য সম্পাদনের উপর ভিত্তি করে একটি ভাল উপসর্গ এবং প্রত্যয় যুক্ত করা সংঘর্ষের আরও কম সুযোগ সরবরাহ করবে।
পলিমেশ

@ পলিমেশ আপনি অস্থায়ী ডিরেক্টরি তৈরি করে তার মধ্যে একটি নির্দিষ্ট নাম ফাইল ব্যবহার করে দৌড়ের অবস্থা এড়াতে পারবেন। সুতরাং আপনার ফাংশন কোনও ফাইলের পরিবর্তে একটি ডিরেক্টরি গ্রহণ করে এবং সর্বদা একই ফাইল তৈরি করে।
ডিলান ইয়ং

ট্যারিফাইল ব্যবহার করুন এবং এটি ফাইলবজটি পাস করুন
ওয়াইর্মউড

উত্তর:


67

আপনি যদি কোনও টেম্প ফাইলের নাম চান তবে আপনি কেবল অভ্যন্তরীণ টেম্পাইল ফাংশনটি কল করতে পারেন _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 

4
temp_dir = tempfile.mkdtemp(prefix='some-prefix_')একটি অস্থায়ী ডিরেক্টরি তৈরির আরও ভাল উপায় যা নিরাপদে একটি অস্থায়ী ডিরেক্টরি তৈরি করবে এবং পরম পথের সাথে একটি স্ট্রিং ফিরিয়ে আনবে।
ইমানুয়েল

4
এটি উল্লেখ করা গুরুত্বপূর্ণ যে next(tempfile._get_candidate_names())অগত্যা অ-অস্তিত্বহীন পথটি ফেরত দেয় না, এজন্যই ব্যবহারকারী-স্তরের টেম্পাইল ফাইলগুলি কোনও অব্যবহৃত না পাওয়া পর্যন্ত বিভিন্ন নাম ব্যবহার করতে পারে :
এলি করভিগো

4
কেউ tempfile.gettempdir()ব্যক্তিগত পরিবর্তে পাবলিক ব্যবহার করতে পারে tempfile._get_default_tempdir()
flonk

@ ইমানুয়েলএ এটি মনে রাখা গুরুত্বপূর্ণ tempfile.mkdtempযে ব্যবহারকারীর অস্থায়ী ডিরেক্টরি এবং এটির সাথে কাজ করার সময় এর বিষয়বস্তু মোছার জন্য দায়বদ্ধ।
ড্যানিয়েল ব্রাউন

49

আমি মনে করি এটি করার সবচেয়ে সহজ, সবচেয়ে সুরক্ষিত উপায় হ'ল এইরকম:

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

একটি অস্থায়ী ডিরেক্টরি তৈরি করা হয় যা কেবলমাত্র আপনি অ্যাক্সেস করতে পারবেন, তাই কোনও সুরক্ষা সমস্যা নেই, তবে এতে কোনও ফাইল তৈরি করা উচিত নয়, যাতে আপনি সেই ডিরেক্টরিতে যে ফাইল ফাইল তৈরি করতে চান তা চয়ন করতে পারেন।

সম্পাদনা: পাইথন 3 এ আপনি এখন tempfile.TemporaryDirectory()মুছে ফেলার ব্যবস্থাপনার জন্য প্রসঙ্গ পরিচালক হিসাবে ব্যবহার করতে পারেন :

with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, 'something')
  # use path

4
ড্যানিয়েল ব্রাউন যেমন উপরে উল্লিখিত হয়েছে: এটি মনে রাখা গুরুত্বপূর্ণ tempfile.mkdtempযে ব্যবহারকারীর অস্থায়ী ডিরেক্টরি এবং এর সামগ্রীগুলি মুছে ফেলার জন্য দায়বদ্ধ যখন এটি করা হয়।
বিটাইনর্ট

5
আপনি যদি tempfile.TemporaryDirectory()প্রসঙ্গ পরিচালক হিসাবে ব্যবহার করেন তবে এটি আপনার জন্য মুছে ফেলা হবে।
জিরিট

16

কিছুটা দেরি হতে পারে তবে এতে কিছু ভুল আছে কি?

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

39
এই কোডটি নামটির জন্য অস্থায়ী ফাইলটি তৈরি করবে, যেখানে প্রশ্নটিতে বলা হয়েছে without creating actual file in Python
জাকুব কুকুল

এটি প্রশ্নের উত্তর দেয় না
উত্তোলন করুন

9

tempfile.mktemp() এটা কর.

তবে মনে রাখবেন এটি অবনমিত হয়েছে। তবে এটি ফাইলটি তৈরি করবে না এবং এটি ব্যবহারের তুলনায় অস্থিরতায় একটি সরকারী ফাংশন _get_candidate_names()

এটি অবহিত হওয়ার কারণ হ'ল এটি কল করা এবং আসলে ফাইলটি তৈরি করার চেষ্টা করার মধ্যে সময়ের ব্যবধান। তবে আমার ক্ষেত্রে এটির সম্ভাবনা এত পাতলা এবং এটি ব্যর্থ হলেও তা গ্রহণযোগ্য হবে। তবে আপনার ইউজকেসটির জন্য মূল্যায়ন করা আপনার উপর নির্ভর করে।


4
"এমনকি যদি এটি ব্যর্থ হয় তবে তা গ্রহণযোগ্য হবে"; দৌড়ের অবস্থাটি কেবল ব্যর্থতার ঝুঁকি নয়, এটি একটি সুরক্ষা ঝুঁকি ( tempfile.mktempডকুমেন্টেশন দেখুন)। সুতরাং এটি গ্রহণযোগ্য বলে মনে করা উচিত নয়।
বিগনোজ

5
@ বিগনোজ এটি একটি সম্ভাব্য সুরক্ষা সমস্যা। এটি আপনি যা করতে চান তার উপর নির্ভর করে, আপনি কার্যকর করার পরিবেশ ইত্যাদি in ইত্যাদি যা বলেছিল: এটি os.path.join(tempfile.mkdtemp(), 'something')অন্তত ডিরেক্টরি তৈরি করা হয়েছে (এবং আপনার ধারণার মালিকানায় আমি মনে করি) এর মতো কিছু করা আরও সুরক্ষিত হতে পারে ।
অ্যালেক

5

পূর্ববর্তী উত্তরগুলির সংমিশ্রণে আমার সমাধানটি হ'ল:

def get_tempfile_name(some_id):
    return os.path.join(tempfile.gettempdir(), next(tempfile._get_candidate_names()) + "_" + some_id)

আপনার some_idপ্রয়োজন না হলে al চ্ছিক করুন ।


আবার, প্রার্থীর নামগুলি সম্ভবত উপলভ্য নাও হতে পারে। : এটা সঠিক উত্তর stackoverflow.com/a/45803022/6387880
j4hangir

4
তবে সম্ভবত একটি এলোমেলো নাম তৈরি করা প্রয়োজন। তবুও, নিশ্চিত হওয়ার জন্য, যদি _get_candidate_names()অস্তিত্ব না থাকে তবে কেউ কেউ কিছু অর্ধ-এলোমেলো স্ট্রিং জেনারেটরে ডিফল্ট করতে পারেন। উদাহরণস্বরূপ কিছু uuid।
juanmarkes

4

জোয়াকিম ইসাকসন মন্তব্যগুলিতে যেমন বলেছিলেন, আপনি যদি কেবল একটি নাম পান তবে আপনার প্রোগ্রামটি করার আগে অন্য কোনও প্রোগ্রামের নামটি ব্যবহার করার ক্ষেত্রে সমস্যা হতে পারে। সম্ভাবনাগুলি পাতলা, তবে অসম্ভব নয়।

সুতরাং এই পরিস্থিতিতে নিরাপদ কাজটি হ'ল সম্পূর্ণ GzipFile () কনস্ট্রাক্টর ব্যবহার করুন, যার স্বাক্ষর রয়েছে GzipFile( [filename[, mode[, compresslevel[, fileobj]]]])। আপনি চাইলে এটি ওপেন ফাইলবজ এবং একটি ফাইলের নামও পাস করতে পারেন। বিশদ জন্য gzip ডক্স দেখুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.