উইন্ডোজ একটি অস্থায়ী ডিরেক্টরি তৈরি?


126

উইন্ডোজে কোনও টেম্প ডিরেক্টরি ডিরেক্টরি পাওয়ার সবচেয়ে ভাল উপায় কী? আমি দেখতে পাচ্ছি যে আমি একটি অস্থায়ী ফাইল তৈরি করতে GetTempPathএবং GetTempFileNameতৈরি করতে পারি , তবে mkdtempঅস্থায়ী ডিরেক্টরি তৈরির জন্য লিনাক্স / বিএসডি ফাংশনের সমতুল্য কি আছে ?


এই প্রশ্নটি খুঁজে পাওয়া একটু কঠিন বলে মনে হচ্ছে। বিশেষত, আপনি স্ট্যাক ওভারফ্লো অনুসন্ধান বাক্সে "অস্থায়ী ডিরেক্টরি। নেট" এর মতো জিনিসগুলি টাইপ করলে এটি প্রদর্শিত হবে না। এটি দুর্ভাগ্যজনক বলে মনে হচ্ছে, যেহেতু উত্তরগুলি এখন পর্যন্ত সমস্ত .NET উত্তর। আপনি কি মনে করেন আপনি "নেট" ট্যাগটি যুক্ত করতে পারেন? (এবং সম্ভবত "ডিরেক্টরি" বা "অস্থায়ী-ডিরেক্টরি" ট্যাগ?) অথবা শিরোনামে ".NET" শব্দটি যুক্ত করতে পারেন? হতে পারে প্রশ্ন বডি বিকল্পে "অস্থায়ী" সাথে "টেম্প" বলছে - তাই আপনি যদি সংক্ষিপ্ত ফর্মটি অনুসন্ধান করেন তবে আপনি একটি ভাল পাঠ্য অনুসন্ধানের মিল পাবেন। আমি নিজেকে এই জিনিসগুলি করার মতো যথেষ্ট প্রতিনিধি বলে মনে করি না। ধন্যবাদ।
ক্রিস

ঠিক আছে, আমি একটি নন-নেট উত্তর খুঁজছিলাম, তাই আমি এটি ছেড়ে যেতে পছন্দ করি, তবে আপনি যে প্রস্তাবিত অন্য সম্পাদনাগুলি করেছিলেন তা আমি করেছি। ধন্যবাদ।
জোশ কেলি

@ জোশ কেলি: আমি কেবল উইন 32 এপিআই-কে ডাবল-চেক করেছি এবং সেখানে কেবলমাত্র বিকল্পগুলি হল টেম্পথ পাথ পাওয়ার অনুরূপ পদ্ধতির অনুসরণ করতে হবে, একটি র‌্যামডো ফাইলের নাম তৈরি করে একটি ডিরেক্টরি তৈরি করতে হবে।
স্কট ডরম্যান

উত্তর:


230

না, mkdtemp এর সমতুল্য নেই। গেটটিম্পপথ এবং গেটর্যান্ডমফিলনামের সংমিশ্রণটি ব্যবহার করা সবচেয়ে ভাল বিকল্প

আপনার এই মত কোড প্রয়োজন হবে:

public string GetTemporaryDirectory()
{
   string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
   Directory.CreateDirectory(tempDirectory);
   return tempDirectory;
}

3
এটি কিছুটা বিপজ্জনক বলে মনে হচ্ছে। বিশেষত, একটি সুযোগ আছে (ছোট, তবে শূন্য নয়, ডান?) যে পথটি ।কোমাইন (Path.GetTempPath (), Path.GetRandomFileName ()) ইতিমধ্যে বিদ্যমান একটি ডিরেক্টরিটির নাম ফিরিয়ে দেবে। যেহেতু ডিরেক্টরি। ক্রিয়েট ডিরেক্টরী (টেমপ্লেয়ার্ট্রি) টেম্পডেরেটরি ইতিমধ্যে বিদ্যমান থাকলে একটি ব্যতিক্রম ছুঁড়ে ফেলবে না, আপনার আবেদন দ্বারা এই কেসটি সনাক্ত করা যাবে না। এবং তারপরে আপনার দুটি একে অপরের কাজে পদক্ষেপ নিতে পারে। .NET- র কোন নিরাপদ বিকল্প আছে?
ক্রিস

22
@ ক্রিস: গেটআরন্ডমফাইনেম পদ্ধতিটি একটি ক্রিপ্টোগ্রাফিকভাবে শক্তিশালী, এলোমেলো স্ট্রিং দেয় যা ফোল্ডারের নাম বা কোনও ফাইলের নাম হিসাবে ব্যবহার করা যেতে পারে। আমি অনুমান করি যে তাত্ত্বিকভাবে সম্ভব যে ফলস্বরূপ পথটি ইতিমধ্যে বিদ্যমান থাকতে পারে তবে এটি করার জন্য অন্য কোনও উপায় নেই। আপনি যদি পথটি বিদ্যমান কিনা তা পরীক্ষা করে দেখতে পারে এবং যদি এটি আবার পথ বলে .GetRandomFileName () আবার কল করে এবং পুনরাবৃত্তি করে।
স্কট ডরম্যান

5
@ ক্রিস: হ্যাঁ, আপনি যদি সেই পরিমাণে সুরক্ষা নিয়ে উদ্বিগ্ন হন তবে খুব পাতলা সম্ভাবনা রয়েছে যে অন্য একটি প্রক্রিয়া পাথ.কোমাইন এবং ডিরেক্টরিটির মধ্যে ডিরেক্টরি তৈরি করতে পারে re
স্কট ডরম্যান

8
গেটআরন্ডমফিলনেম 11 টি এলোমেলো ছোট ছোট অক্ষর এবং সংখ্যা উত্পন্ন করে যার অর্থ ডোমেন আকার (26 + 10) ^ 11 = ~ 57 বিট। আপনি এটি বর্গক্ষেত্রের জন্য সর্বদা দুটি কল করতে পারেন
মার্টি নীল

27
ডিরেক্টরিটি অস্তিত্বহীন রয়েছে তা যাচাই করার পরে, theশ্বর মহাবিশ্বকে থামিয়ে দিতে পারেন, আপনি লিখতে চলেছেন এমন সমস্ত ফাইলের সাথে একই ডিরেক্টরি তৈরি করতে পারে, যার ফলে আপনার অ্যাপ্লিকেশনটি ফুটিয়ে উঠবে, কেবল আপনার দিনটি নষ্ট করবে।
ট্রায়ঙ্কো

25

আমি হ্যাক Path.GetTempFileName() ডিস্কে আমাকে একটি বৈধ, সিউডো-এলোমেলো ফাইলপথ দিতে , তারপরে ফাইলটি মুছুন এবং একই ফাইলের পথ দিয়ে একটি ডিরেক্টরি তৈরি করুন।

স্কট ডোরম্যানের উত্তরের ক্রিসের মন্তব্য অনুযায়ী ফাইলপথটি কিছুক্ষণের মধ্যে বা লুপে পাওয়া যায় কিনা তা যাচাই করার প্রয়োজনীয়তা এড়িয়ে যায়।

public string GetTemporaryDirectory()
{
  string tempFolder = Path.GetTempFileName();
  File.Delete(tempFolder);
  Directory.CreateDirectory(tempFolder);

  return tempFolder;
}

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


7

আমি getTempPath (), CoCreateGuid (), এবং MakeDirectory () এর মতো একটি জিইউইডি-তৈরির ফাংশন ব্যবহার করতে চাই।

একটি জিইউডিকে স্বতন্ত্রতার উচ্চ সম্ভাবনা তৈরি করার জন্য ডিজাইন করা হয়েছে, এবং এটি অত্যন্ত অসম্ভব যে কেউ কেউ নিজেই জিইউইডি হিসাবে একই ফর্মের সাথে একটি ডিরেক্টরি তৈরি করতে পারে (এবং যদি তারা এটি করে তবে ক্রিয়েট ডিরেক্টরী () তার অস্তিত্বের ইঙ্গিত দেয় না।)


5

@Chris। আমিও দূরবর্তী ঝুঁকিতে পড়েছিলাম যে অস্থায়ী ডিরেক্টরি ইতিমধ্যে উপস্থিত থাকতে পারে। এলোমেলো এবং ক্রিপ্টোগ্রাফিকভাবে শক্তিশালী সম্পর্কে আলোচনাগুলি আমাকে পুরোপুরি সন্তুষ্ট করে না।

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

    [DllImport(@"kernel32.dll", EntryPoint = "CreateDirectory", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CreateDirectoryApi
        ([MarshalAs(UnmanagedType.LPTStr)] string lpPathName, IntPtr lpSecurityAttributes);

    /// <summary>
    /// Creates the directory if it does not exist.
    /// </summary>
    /// <param name="directoryPath">The directory path.</param>
    /// <returns>Returns false if directory already exists. Exceptions for any other errors</returns>
    /// <exception cref="System.ComponentModel.Win32Exception"></exception>
    internal static bool CreateDirectoryIfItDoesNotExist([NotNull] string directoryPath)
    {
        if (directoryPath == null) throw new ArgumentNullException("directoryPath");

        // First ensure parent exists, since the WIN Api does not
        CreateParentFolder(directoryPath);

        if (!CreateDirectoryApi(directoryPath, lpSecurityAttributes: IntPtr.Zero))
        {
            Win32Exception lastException = new Win32Exception();

            const int ERROR_ALREADY_EXISTS = 183;
            if (lastException.NativeErrorCode == ERROR_ALREADY_EXISTS) return false;

            throw new System.IO.IOException(
                "An exception occurred while creating directory'" + directoryPath + "'".NewLine() + lastException);
        }

        return true;
    }

আপনারা সিদ্ধান্ত নিতে পারেন যে পরিচালনা / পির চালিত কোডের "ব্যয় / ঝুঁকি" মূল্যবান কিনা। বেশিরভাগই বলবেন এটি তা নয় তবে কমপক্ষে আপনার এখন একটি পছন্দ রয়েছে।

ক্রিয়েটপ্যারেন্টফোল্ডার () ছাত্রের অনুশীলন হিসাবে ছেড়ে যায়। আমি ডিরেক্টরি ব্যবহার করি। ক্রিয়েট ডিরেক্টরী ()। ডিরেক্টরিটির পিতামাতাকে পেতে সাবধান হন, যেহেতু এটি যখন মূল হয় তখন শূন্য থাকে।


5

আমি সাধারণত এটি ব্যবহার করি:

    /// <summary>
    /// Creates the unique temporary directory.
    /// </summary>
    /// <returns>
    /// Directory path.
    /// </returns>
    public string CreateUniqueTempDirectory()
    {
        var uniqueTempDir = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));
        Directory.CreateDirectory(uniqueTempDir);
        return uniqueTempDir;
    }

আপনি যদি পুরোপুরি নিশ্চিত হতে চান যে এই ডিরেক্টরিটির নামটি অস্থায়ী পথে উপস্থিত থাকবে না তবে আপনার এই অনন্য ডিরেক্টরিটির নামটি আছে কিনা তা পরীক্ষা করে দেখতে হবে এবং এটি সত্যই উপস্থিত থাকলে অন্যটি তৈরি করার চেষ্টা করতে হবে।

তবে এই জিইউইডি-ভিত্তিক বাস্তবায়ন যথেষ্ট। এক্ষেত্রে আমার কোনও সমস্যা নিয়ে অভিজ্ঞতা নেই। কিছু এমএস অ্যাপ্লিকেশনগুলি জিইউডি ভিত্তিক টেম্প ডিরেক্টরিগুলিও ব্যবহার করে।


1

GetTempPath এটি করার সঠিক উপায়; আমি নিশ্চিত না যে এই পদ্ধতি সম্পর্কে আপনার উদ্বেগ কী। তারপরে আপনি এটি তৈরি করতে তৈরিডাইরেক্টরি ব্যবহার করতে পারেন।


একটি সমস্যা হ'ল getTempFileName একটি শূন্য-বাইট ফাইল তৈরি করবে। পরিবর্তে আপনাকে getTempPath, GetRandomFileName এবং ক্রিয়েট ডিরেক্টরি ব্যবহার করতে হবে।
স্কট ডরম্যান

যা সূক্ষ্ম, সম্ভব এবং করণীয়। আমি কোড সরবরাহ করতে যাচ্ছিলাম তবে ডরম্যান এটি আমার আগে পেয়েছিল এবং এটি সঠিকভাবে কাজ করে।

1

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

সংঘর্ষের সম্ভাবনা কম হওয়ার জন্য ডিরেক্টরিটির নামের সাথে অন্য কোনও প্রক্রিয়া বা সমাবেশ সম্পর্কিত তথ্য যুক্ত হতে পারে, যদিও অস্থায়ী ডিরেক্টরি নামটিতে এ জাতীয় তথ্য দৃশ্যমান করা বাঞ্ছনীয় নয়। ফোল্ডারের নামগুলিকে আরও এলোমেলো দেখানোর জন্য সময় সম্পর্কিত ক্ষেত্রগুলি একত্রিত করার সাথে কোনওটি ক্রমও মেশাতে পারে। আমি ব্যক্তিগতভাবে এটিকে সেভাবেই ছেড়ে দেওয়া পছন্দ করি কারণ ডিবাগিংয়ের সময় আমার পক্ষে সেগুলি খুঁজে পাওয়া আরও সহজ।

string randomlyGeneratedFolderNamePart = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

string timeRelatedFolderNamePart = DateTime.Now.Year.ToString()
                                 + DateTime.Now.Month.ToString()
                                 + DateTime.Now.Day.ToString()
                                 + DateTime.Now.Hour.ToString()
                                 + DateTime.Now.Minute.ToString()
                                 + DateTime.Now.Second.ToString()
                                 + DateTime.Now.Millisecond.ToString();

string processRelatedFolderNamePart = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();

string temporaryDirectoryName = Path.Combine( Path.GetTempPath()
                                            , timeRelatedFolderNamePart 
                                            + processRelatedFolderNamePart 
                                            + randomlyGeneratedFolderNamePart);

0

উপরে উল্লিখিত হিসাবে, Path.GetTempPath () এটি করার এক উপায়। আপনি কল করতে পারে যদি পরিবেশকেও বলতে পারেন vironmentGEENEVENNNVAWATEWEBET ("TEMP") যদি ব্যবহারকারীর একটি TEMP এনভায়রনমেন্ট ভেরিয়েবল সেট আপ থাকে।

আপনি যদি অ্যাপ্লিকেশনটিতে টেম্প ডিরেক্টরিটি অব্যাহত ডেটার মাধ্যম হিসাবে ব্যবহার করার পরিকল্পনা করে থাকেন তবে আপনার সম্ভবত আইসোলেটেড স্টোরেজটি কনফিগারেশন / রাজ্য / ইত্যাদির সংগ্রহস্থল হিসাবে ব্যবহার করা উচিত ...

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