C # में अद्वितीय फ़ाइल नाम कैसे उत्पन्न करें


131

मैंने एक एल्गोरिथ्म लागू किया है जो फ़ाइलों के लिए अद्वितीय नाम उत्पन्न करेगा जो हार्ड ड्राइव पर बचाएगा। मैं अपील कर रहा हूं DateTime: घंटे, मिनट, दूसरा और मिलीसेकंड लेकिन फिर भी यह फाइलों का डुप्लिकेट नाम उत्पन्न करता है क्योंकि एक समय में कई फाइलें अपलोड करता है।

हार्ड ड्राइव पर संग्रहीत की जाने वाली फ़ाइलों के लिए अद्वितीय नाम उत्पन्न करने के लिए सबसे अच्छा समाधान क्या है ताकि कोई 2 फाइलें समान न हों?


यह अन्य आवश्यकताओं पर निर्भर करता है; यह [पुराना] सवाल था / बहुत अस्पष्ट है।
user2864740

जवाबों:


240

यदि पठनीयता कोई मायने नहीं रखती है, तो GUID का उपयोग करें ।

उदाहरण के लिए:

var myUniqueFileName = string.Format(@"{0}.txt", Guid.NewGuid());

या इससे कम :

var myUniqueFileName = $@"{Guid.NewGuid()}.txt";

मेरे कार्यक्रमों में, मैं कभी-कभी 10 बार उदाहरण के लिए एक पठनीय नाम ("Image1.png" ... "Image10.png") उत्पन्न करने की कोशिश करता हूं और अगर वह विफल रहता है (क्योंकि फ़ाइल पहले से मौजूद है), तो मैं वापस GUIDs में आता हूं।

अपडेट करें:

हाल ही में, मैंने DateTime.Now.TicksGUID के बजाय उपयोग किया है:

var myUniqueFileName = string.Format(@"{0}.txt", DateTime.Now.Ticks);

या

var myUniqueFileName = $@"{DateTime.Now.Ticks}.txt";

मेरे लिए लाभ यह है कि यह GUID की तुलना में एक छोटा और "अच्छा दिखने वाला" फ़ाइल नाम बनाता है।

कृपया ध्यान दें कि कुछ मामलों में (जैसे बहुत कम समय में बहुत सारे यादृच्छिक नाम पैदा करना), यह गैर-अद्वितीय मान बना सकता है।

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


7
मुझे एक GUID के रूप में टिक्स का उपयोग करना वास्तव में बदसूरत लगता है। आप टिक्स का हैश भी प्राप्त कर सकते हैं जो फ़ाइल नाम के चरित्र की लंबाई को कम करता है। DateTime.Now.Ticks.GetHashCode().ToString("x").ToUpper()
WillMcKill

4
"टिक्स" प्रेडिक्टेबल है और थ्रेड-सेफ नहीं है (जैसा कि एक ही 'टिक्स' को कई थ्रेड्स / प्रोसेस से प्राप्त किया जा सकता है)। यह अस्थायी फ़ाइल नाम पीढ़ी के लिए उपयुक्त नहीं है। X..1..N उत्पन्न करना उपयोगकर्ता-सामना करने वाले कार्यों (यानी एक्सप्लोरर में प्रतिलिपि) के लिए उपयुक्त हो सकता है, लेकिन सर्वर के काम के लिए संदिग्ध है।
user2864740

90

उपयोग

Path.GetTempFileName()

या नए GUID () का उपयोग करें।

Path.GetTempFilename () MSDN पर


: यहाँ MSDN दस्तावेज़ के लिए लिंक है msdn.microsoft.com/en-us/library/...
epotter

3
ध्यान दें कि, GetTempFileName()यदि आप उन्हें हटाए बिना ऐसी कई फाइलें बनाते हैं , तो वह एक अपवाद फेंक सकता है।
जॉय

21
"GetTempFileName विधि IOException को बढ़ाएगी यदि इसका उपयोग पिछली अस्थायी फ़ाइलों को हटाने के बिना 65535 से अधिक फ़ाइलों को बनाने के लिए किया जाता है।" MSDN लेख कहता है।
atağdaş Tekin

1
चेतावनी: GetTempFileNameहोगा बनाने के एक फ़ाइल। इसका मतलब यह भी है कि यह अस्थायी पथ स्थान चुनता है । दूसरी ओर, GetRandomFileNameएक 8.3 फ़ाइल नाम उत्पन्न करने के लिए उपयुक्त है जिसे एक अलग पथ के साथ उपयोग किया जा सकता है। (मैंने कुछ डरावने कोड देखे हैं जो एक फ़ाइल के साथ GetTempFileName का उपयोग करता है। केवल फ़ाइल नाम का उपयोग कहीं और करने के लिए।)
user2864740

77
System.IO.Path.GetRandomFileName()

Path.GetRandomFileName () MSDN पर


: यहाँ MSDN दस्तावेज़ के लिए लिंक है msdn.microsoft.com/en-us/library/...
epotter

13
@RyBolt: चूंकि आपको अपने आप को बीज नहीं डालना है, इसलिए आपको इस पद्धति का उपयोग करने के लिए बहुत कुछ नहीं रखना है। और मुझे उम्मीद है कि सुरक्षित क्रिप्टोग्राफिक सिस्टम बनाने के बारे में डेवलपर्स के विशाल बहुमत का कोई सुराग नहीं होगा।
जॉय

54

यदि फ़ाइल नाम की पठनीयता महत्वपूर्ण नहीं है, तो GUID, जैसा कि बहुत से सुझाएगा। हालाँकि, मुझे लगता है कि 1000 GUID फ़ाइल नामों वाली एक निर्देशिका को देखना बहुत कठिन है। इसलिए मैं आमतौर पर एक स्थिर स्ट्रिंग के संयोजन का उपयोग करता हूं जो फ़ाइल नाम को कुछ संदर्भ जानकारी, टाइमस्टैम्प और GUID देता है।

उदाहरण के लिए:

public string GenerateFileName(string context)
{
    return context + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + Guid.NewGuid().ToString("N");
}

filename1 = GenerateFileName("MeasurementData");
filename2 = GenerateFileName("Image");

इस तरह, जब मैं फ़ाइल नाम से सॉर्ट करता हूं, तो यह स्वचालित रूप से फाइलों को संदर्भ स्ट्रिंग द्वारा समूहित करेगा और टाइमस्टैम्प द्वारा सॉर्ट करेगा।

ध्यान दें कि विंडोज़ में फ़ाइल नाम की सीमा 255 वर्ण है।


1
+1 GUID के साथ संयुक्त उपयोगी जानकारी शामिल करने के सुझाव के लिए । - नमक के एक दाने के साथ लेने के लिए एक तरफ: एक फ़ाइल नाम में तारीख और समय सहित जब आप बस कर सकते हैं बेमानी की तरह है Right Click > Sort By > Date
टिमोथी शील्ड

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

होना चाहिए Guid.NewGuid().ToString();। गुम कोष्ठक। +1 अन्यथा
लॉरेंट डब्ल्यू।

यह बहुत ही चालाक है। टाइमस्टैम्प और गाइड। +1
जोशिएट्स 1980

मुझे यह समाधान पसंद है +1, मैंने एक दूसरा पैरामीटर स्ट्रिंग एक्सटेंशन जोड़ा है जिसे मैं फ़ाइलनाम में जोड़ता हूं, यह आगे संदर्भ के विचार का समर्थन करता है और यदि आवश्यक हो तो डिफ़ॉल्ट रूप से फ़ाइल को डबल क्लिक पर खोलने की अनुमति देता है
शेल्बीपेरेरा

23

यहां एक एल्गोरिथ्म है जो मूल आपूर्ति के आधार पर एक अद्वितीय पठनीय फ़ाइलनाम देता है। यदि मूल फ़ाइल मौजूद है, तो यह गुप्त रूप से फ़ाइल नाम के लिए एक सूचकांक को जोड़ने की कोशिश करता है जब तक कि यह एक ऐसा नहीं है जो मौजूद नहीं है। यह मौजूदा फ़ाइल नाम को हैशसेट में टकराव की जाँच करने के लिए पढ़ता है, इसलिए यह बहुत जल्दी है (मेरी मशीन पर प्रति सेकंड कुछ सौ फ़ाइलनाम), यह थ्रेड सुरक्षित भी है, और दौड़ की स्थिति से ग्रस्त नहीं है।

उदाहरण के लिए, यदि आप इसे पास करते हैं test.txt, तो यह इस क्रम में फाइल बनाने का प्रयास करेगा:

test.txt
test (2).txt
test (3).txt

आदि। आप अधिकतम प्रयासों को निर्दिष्ट कर सकते हैं या बस इसे डिफ़ॉल्ट पर छोड़ सकते हैं।

यहाँ एक पूर्ण उदाहरण है:

class Program
{
    static FileStream CreateFileWithUniqueName(string folder, string fileName, 
        int maxAttempts = 1024)
    {
        // get filename base and extension
        var fileBase = Path.GetFileNameWithoutExtension(fileName);
        var ext = Path.GetExtension(fileName);
        // build hash set of filenames for performance
        var files = new HashSet<string>(Directory.GetFiles(folder));

        for (var index = 0; index < maxAttempts; index++)
        {
            // first try with the original filename, else try incrementally adding an index
            var name = (index == 0)
                ? fileName
                : String.Format("{0} ({1}){2}", fileBase, index, ext);

            // check if exists
            var fullPath = Path.Combine(folder, name);
            if(files.Contains(fullPath))
                continue;

            // try to create the file
            try
            {
                return new FileStream(fullPath, FileMode.CreateNew, FileAccess.Write);
            }
            catch (DirectoryNotFoundException) { throw; }
            catch (DriveNotFoundException) { throw; }
            catch (IOException) 
            {
                // Will occur if another thread created a file with this 
                // name since we created the HashSet. Ignore this and just
                // try with the next filename.
            } 
        }

        throw new Exception("Could not create unique filename in " + maxAttempts + " attempts");
    }

    static void Main(string[] args)
    {
        for (var i = 0; i < 500; i++)
        {
            using (var stream = CreateFileWithUniqueName(@"c:\temp\", "test.txt"))
            {
                Console.WriteLine("Created \"" + stream.Name + "\"");
            }
        }

        Console.ReadKey();
    }
}

धागा-सुरक्षित ? नहींstatic readonly चरlock?
कीकेनेट

यह विधि स्वयं स्थिर है इसलिए कुछ भी साझा नहीं किया जाता है, इसलिए मेरा मानना ​​है कि कई सूत्र सुरक्षित रूप से इस पद्धति में प्रवेश कर सकते हैं। शायद थ्रेड-सेफ काफी सही शब्द नहीं है - मैं यह बताने की कोशिश कर रहा हूं कि यदि निष्पादन के दौरान एक अन्य थ्रेड / प्रक्रिया एक परस्पर विरोधी नाम के साथ एक फ़ाइल बनाती है, तो यह विधि ठीक हो जाती है और अगले उपलब्ध नाम की कोशिश करती है। यदि आपको लगता है कि इसमें सुधार किया जा सकता है तो बेझिझक संपादित करें।
माइक चेम्बरलेन

शायद "दौड़ की स्थिति से पीड़ित नहीं" इसे लगाने का एक बेहतर तरीका है।
माइक चेम्बरलेन

10

मैं GetRandomFileName का उपयोग करता हूं :

GetRandomFileName विधि एक क्रिप्टोग्राफिक रूप से मजबूत, यादृच्छिक स्ट्रिंग देता है जिसे किसी फ़ोल्डर नाम या फ़ाइल नाम के रूप में उपयोग किया जा सकता है। GetTempFileName के विपरीत, GetRandomFileName एक फ़ाइल नहीं बनाता है। जब आपकी फ़ाइल सिस्टम की सुरक्षा सर्वोपरि है, तो GetTempFileName के बजाय इस विधि का उपयोग किया जाना चाहिए।

उदाहरण:

public static string GenerateFileName(string extension="")
{
    return string.Concat(Path.GetRandomFileName().Replace(".", ""),
        (!string.IsNullOrEmpty(extension)) ? (extension.StartsWith(".") ? extension : string.Concat(".", extension)) : "");
}

क्या GetRandomFileName () विधि हमेशा GUID () के समान हर बार अद्वितीय फ़ाइल नाम उत्पन्न करती है?
आशीष शुक्ला

1
@ आशीष शुक्ला वास्तव में मुझे कोई पता नहीं है। msdn का कहना है कि "एक क्रिप्टोग्राफिक रूप से मजबूत, यादृच्छिक स्ट्रिंग" उत्पन्न होता है। मुझे अब तक कोई समस्या नहीं थी। यदि विशिष्टता महत्वपूर्ण है, तो एक अतिरिक्त जांच एक अच्छा विचार हो सकता है।
कोरा

3
  1. अपनी सामान्य प्रक्रिया का पालन करते हुए अपना टाइमस्टैम्ड फ़ाइल नाम बनाएं
  2. यह देखने के लिए जांचें कि क्या फ़ाइल नाम मौजूद है या नहीं
  3. झूठी - फ़ाइल को बचाने के लिए
  4. सच - फ़ाइल के लिए अतिरिक्त वर्ण, शायद एक काउंटर
  5. चरण 2 पर जाएं

10
यह एल्गोरिथ्म सुरीला है
Jader Dias

3

आपके पास बिना किसी कस्टम तरीके के आपके लिए एक विशिष्ट फ़ाइल नाम अपने आप उत्पन्न हो सकता है। बस के साथ निम्न का उपयोग StorageFolder क्लास या StorageFile क्लास । यहाँ कुंजी है:CreationCollisionOption.GenerateUniqueName औरNameCollisionOption.GenerateUniqueName

करने के लिए बनाने के लिए एक अनूठा फ़ाइल नाम के साथ एक नई फ़ाइल:

var myFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("myfile.txt", NameCollisionOption.GenerateUniqueName);

फ़ाइल को एक अद्वितीय फ़ाइल नाम के साथ किसी स्थान पर कॉपी करने के लिए:

var myFile2 = await myFile1.CopyAsync(ApplicationData.Current.LocalFolder, myFile1.Name, NameCollisionOption.GenerateUniqueName);

गंतव्य स्थान में एक अद्वितीय फ़ाइल नाम के साथ एक फ़ाइल स्थानांतरित करने के लिए :

await myFile.MoveAsync(ApplicationData.Current.LocalFolder, myFile.Name, NameCollisionOption.GenerateUniqueName);

गंतव्य स्थान में एक अद्वितीय फ़ाइल नाम के साथ एक फ़ाइल का नाम बदलने के लिए :

await myFile.RenameAsync(myFile.Name, NameCollisionOption.GenerateUniqueName);

2

मैं निम्नलिखित कोड और इसके ठीक काम का उपयोग कर रहा हूं। मुझे उम्मीद है कि यह आपकी मदद कर सकता है।

मैं टाइमस्टैम्प का उपयोग करके एक अद्वितीय फ़ाइल नाम से शुरू करता हूं -

"संदर्भ_" + DateTime.Now.ToString ("yyyyMMddHHmmssffff")

सी # कोड -

public static string CreateUniqueFile(string logFilePath, string logFileName, string fileExt)
    {
        try
        {
            int fileNumber = 1;

            //prefix with . if not already provided
            fileExt = (!fileExt.StartsWith(".")) ? "." + fileExt : fileExt;

            //Generate new name
            while (File.Exists(Path.Combine(logFilePath, logFileName + "-" + fileNumber.ToString() + fileExt)))
                fileNumber++;

            //Create empty file, retry until one is created
            while (!CreateNewLogfile(logFilePath, logFileName + "-" + fileNumber.ToString() + fileExt))
                fileNumber++;

            return logFileName + "-" + fileNumber.ToString() + fileExt;
        }
        catch (Exception)
        {
            throw;
        }
    }

    private static bool CreateNewLogfile(string logFilePath, string logFile)
    {
        try
        {
            FileStream fs = new FileStream(Path.Combine(logFilePath, logFile), FileMode.CreateNew);
            fs.Close();
            return true;
        }
        catch (IOException)   //File exists, can not create new
        {
            return false;
        }
        catch (Exception)     //Exception occured
        {
            throw;
        }
    }

1

क्या आपको फ़ाइल नाम में दिनांक समय स्टैम्प की आवश्यकता है?

आप फ़ाइल नाम को GUID बना सकते हैं।


@downvoter डाउन वोट का कोई कारण? एक फ़ाइल नाम के लिए एक GUID इस सवाल पर एक लोकप्रिय जवाब लगता है।
लैरी हिप्प

यह एक दोहराया जवाब है, और मेरे पास डाउनवोट करने के लिए पर्याप्त प्रतिष्ठा नहीं है
जादर डायस

@XMLforDummies मेरा जवाब पहले में से एक था। यह अब ऐसा नहीं लग सकता है क्योंकि यह अब तक केवल घंटे दिखाते हैं। यह एक दोहराया जवाब है क्योंकि यह शायद सही उत्तर है।
लैरी हिप्प


1

कैसे Guid.NewGuid()एक GUID बनाने के लिए उपयोग करने के बारे में और फ़ाइल नाम के रूप में उपयोग (या यदि आप चाहते हैं कि आपके समय टिकट के साथ फ़ाइल नाम का हिस्सा)।


1

मैंने एक सरल पुनरावर्ती फ़ंक्शन लिखा है जो फ़ाइल एक्सटेंशन से पहले एक अनुक्रम संख्या को जोड़कर, विंडोज नाम की फ़ाइल नाम उत्पन्न करता है।

के एक वांछित फ़ाइल पथ को देखते हुए C:\MyDir\MyFile.txt, और फ़ाइल पहले से मौजूद है, यह एक अंतिम फ़ाइल पथ देता हैC:\MyDir\MyFile_1.txt

इसे इस तरह कहा जाता है:

var desiredPath = @"C:\MyDir\MyFile.txt";
var finalPath = UniqueFileName(desiredPath);

private static string UniqueFileName(string path, int count = 0)
{
    if (count == 0)
    {
        if (!File.Exists(path))
        {
            return path;
        }
    }
    else
    {
        var candidatePath = string.Format(
            @"{0}\{1}_{2}{3}",
            Path.GetDirectoryName(path),
            Path.GetFileNameWithoutExtension(path),
            count,
            Path.GetExtension(path));

        if (!File.Exists(candidatePath))
        {
            return candidatePath;
        }
    }

    count++;
    return UniqueFileName(path, count);
}

यह धागा-सुरक्षित या प्रक्रिया-सुरक्षित नहीं है। फ़ाइल के साथ एक दौड़-स्थिति है। फ़ाइल की जाँच और कोई (बाद में माना जाता है) निर्माण। त्रैमासिक, जब एक फ़ाइल बनाए बिना दो बार एक पंक्ति में कहा जाता है तो यह उसी परिणाम को लौटाएगा।
user2864740

1

हम नीचे के रूप में एक अद्वितीय आईडी क्यों नहीं बना सकते हैं।

हम DateTime.Now.Ticks और Guide.NewGuid ()। ToString () को एक साथ संयोजित करने और एक अद्वितीय आईडी बनाने के लिए उपयोग कर सकते हैं।

जैसा कि DateTime.Now.Ticks को जोड़ा जाता है, हम उस तारीख और समय का पता लगा सकते हैं जिस पर अद्वितीय आईडी बनाई गई है।

कृपया कोड देखें।

var ticks = DateTime.Now.Ticks;
var guid = Guid.NewGuid().ToString();
var uniqueSessionId = ticks.ToString() +'-'+ guid; //guid created by combining ticks and guid

var datetime = new DateTime(ticks);//for checking purpose
var datetimenow = DateTime.Now;    //both these date times are different.

हम अद्वितीय आईडी में टिक का हिस्सा भी ले सकते हैं और भविष्य के संदर्भ के लिए तारीख और समय की जांच कर सकते हैं।

आप फ़ाइल नाम के लिए बनाई गई अद्वितीय आईडी संलग्न कर सकते हैं या हमारे आवेदन या वेबसाइट पर उपयोगकर्ताओं के लॉगिन-लॉगआउट के लिए अद्वितीय सत्र आईडी बनाने के लिए उपयोग किया जा सकता है।


GUID होने पर 'टिक्स' से परेशान क्यों?
user2864740

किसी भी परिदृश्य के दौरान, यदि आपको यह जांचने की आवश्यकता है कि अनूठे सत्र का निर्माण कब हुआ है, तो आपको सटीक समय मिलेगा। और यह भी कि विशिष्ट टिक जीवनकाल में केवल एक बार होगा।
जिनेश उंटावेडिडा

तुच्छ रूप से, टिक्स के बारे में यह धारणा अमान्य है: 1) कई पर्यवेक्षक एक ही 'टिक' (थ्रेड / प्रक्रियाएं) और 2 देख सकते हैं) एक ही 'टिक' को एक ही पर्यवेक्षक द्वारा कई बार देखा जा सकता है, अगर यह पर्याप्त तेजी से बढ़ता है।
user2864740

हालांकि, द्वारा बस का उपयोग कर Guid.NewGuid (और कहा कि वास्तव में यह "क्रिप्टोग्राफी द्वारा यादृच्छिक" जो कुछ मामलों में ब्याज की हो सकता है नहीं है अनदेखी), हम उस पर जोर कर सकते हैं, एक पर्याप्त उच्च संभावना के साथ कि हम, के बारे में नहीं तो परवाह नहीं है एक अद्वितीय ID जाएगा उत्पन्न होना - यह 'टिक्स' की तुलना में बहुत अधिक, बहुत अधिक गारंटी है । इस प्रकार, 'टिक्सेस' का ऐसा कोई मूल्य / उपयोग नहीं है जो यहाँ "माध्यमिक" डेटा के रूप में अपेक्षित हो जो फ़ाइल नाम में छाया हुआ हो।
user2864740

(एफडब्ल्यूआईडब्ल्यू: मैंने अभी 'अनूठे समय' के बारे में एक टूटे हुए उल्लिखित दावे के साथ कुछ कोड तय किया है ..)
user2864740

0

यदि आप डेटाइम, घंटे, मिनट आदि रखना चाहते हैं। आप एक स्थिर चर का उपयोग कर सकते हैं। फ़ाइल नाम के लिए इस चर का मान जोड़ें। जब आपने फ़ाइल बनाई है तो आप काउंटर को 0 और वेतन वृद्धि के साथ शुरू कर सकते हैं। इस तरह फ़ाइल नाम निश्चित रूप से अद्वितीय होगा क्योंकि आपके पास फ़ाइल में सेकंड भी होते हैं।


0

मैं आमतौर पर इन पंक्तियों के साथ कुछ करता हूं:

  • एक स्टेम फ़ाइल नाम से शुरू करें ( work.dat1उदाहरण के लिए)
  • CreateNew के साथ इसे बनाने का प्रयास करें
  • यदि वह काम करता है, तो आपको फ़ाइल मिल गई है, अन्यथा ...
  • फ़ाइल नाम में वर्तमान दिनांक / समय मिलाएँ ( work.2011-01-15T112357.datउदाहरण के लिए)
  • फ़ाइल बनाने का प्रयास करें
  • अगर वह काम किया है, तो आपको फ़ाइल मिल गई है, अन्यथा ...
  • फ़ाइल नाम में एक मोनोटोनिक काउंटर मिलाएं (work.2011-01-15T112357.0001.datउदाहरण के लिए (मैं GUIDs नापसंद करता हूं। मैं ऑर्डर / पूर्वानुमान पसंद करता हूं।)
  • फ़ाइल बनाने का प्रयास करें। जब तक आपके लिए कोई फ़ाइल नहीं बन जाती, तब तक काउंटर से टिक करते रहें और पुन: प्रयास करते रहें।

यहाँ एक नमूना वर्ग है:

static class DirectoryInfoHelpers
{
    public static FileStream CreateFileWithUniqueName( this DirectoryInfo dir , string rootName )
    {
        FileStream fs = dir.TryCreateFile( rootName ) ; // try the simple name first

        // if that didn't work, try mixing in the date/time
        if ( fs == null )
        {
            string date = DateTime.Now.ToString( "yyyy-MM-ddTHHmmss" ) ;
            string stem = Path.GetFileNameWithoutExtension(rootName) ;
            string ext  = Path.GetExtension(rootName) ?? ".dat" ;

            ext = ext.Substring(1);

            string fn = string.Format( "{0}.{1}.{2}" , stem , date , ext ) ;
            fs = dir.TryCreateFile( fn ) ;

            // if mixing in the date/time didn't work, try a sequential search
            if ( fs == null )
            {
                int seq = 0 ;
                do
                {
                    fn = string.Format( "{0}.{1}.{2:0000}.{3}" , stem , date , ++seq , ext ) ;
                    fs = dir.TryCreateFile( fn ) ;
                } while ( fs == null ) ;
            }

        }

        return fs ;
    }

    private static FileStream TryCreateFile(this DirectoryInfo dir , string fileName )
    {
        FileStream fs = null ;
        try
        {
            string fqn = Path.Combine( dir.FullName , fileName ) ;

            fs = new FileStream( fqn , FileMode.CreateNew , FileAccess.ReadWrite , FileShare.None ) ;
        }
        catch ( Exception )
        {
            fs = null ;
        }
        return fs ;
    }

}

आप एल्गोरिथ्म को ट्वीक करना चाहते हैं (उदाहरण के लिए फ़ाइल नाम के सभी संभावित घटकों का हमेशा उपयोग करें)। संदर्भ पर निर्भर करता है - अगर मैं उदाहरण के लिए लॉग फाइल बना रहा था, कि मैं अस्तित्व से बाहर घूमना चाहता हूं, तो आप उन सभी को नाम के समान पैटर्न साझा करना चाहेंगे।

कोड सही नहीं है (उदाहरण के लिए पास किए गए डेटा पर कोई जांच नहीं)। और एल्गोरिथ्म सही नहीं है (यदि आप हार्ड ड्राइव या मुठभेड़ अनुमतियों को भरते हैं, तो वास्तविक I / O त्रुटियां या अन्य फ़ाइल सिस्टम त्रुटियां, उदाहरण के लिए, यह लटका होगा, जैसा कि यह अनंत लूप में है)।


0

मैं दिन महीना वर्ष के दूसरे मिलिसेकंड स्ट्रिंग के साथ GUID को समाप्त कर रहा हूं और मुझे लगता है कि यह समाधान मेरे परिदृश्य में काफी अच्छा है


0

आप एक यादृच्छिक संख्या उत्पन्न करने के लिए random.Next () का भी उपयोग कर सकते हैं। आप MSDN लिंक देख सकते हैं: http://msdn.microsoft.com/en-us/library/9b3ta19y.aspx


2
मैं इसे अनुशंसित नहीं करूंगा, क्योंकि इसे यादृच्छिक होने की आवश्यकता नहीं है। यह अद्वितीय होना चाहिए।
अधिकतम

0

मैंने ऐसा करने के लिए विशेष रूप से एक वर्ग लिखा था। यह एक "आधार" भाग (एक मिनट-सटीक टाइमस्टैम्प के लिए चूक) के साथ आरंभिक है और इसके बाद अद्वितीय नाम बनाने के लिए पत्रों को जोड़ता है। इसलिए, यदि पहला स्टैम्प उत्पन्न होता है तो 1907101215a, दूसरा 1907101215 बी, फिर 1907101215 सी, वगैरह होगा।

अगर मुझे 25 से अधिक अद्वितीय टिकटों की आवश्यकता है, तो मैं 25 की गिनती के लिए यूरी के z का उपयोग करता हूं। तो, यह 1907101215y, 1907101215za, 1907101215zb, ... 1907101215zzy, 1907101215zza, 1907101215zzb, और आगे जाता है। यह गारंटी देता है कि स्टैम्प हमेशा अल्फ़ान्यूमेरिक रूप से उस क्रम में क्रमबद्ध होंगे, जो वे उत्पन्न हुए थे (जब तक कि स्टैम्प के बाद अगला वर्ण अक्षर नहीं है)।

यह थ्रेड-सेफ नहीं है, स्वचालित रूप से समय को अपडेट नहीं करता है, और जल्दी से फुलाता है यदि आपको सैकड़ों टिकटों की आवश्यकता है, लेकिन मुझे यह मेरी आवश्यकताओं के लिए पर्याप्त लगता है।

/// <summary>
/// Class for generating unique stamps (for filenames, etc.)
/// </summary>
/// <remarks>
/// Each time ToString() is called, a unique stamp is generated.
/// Stamps are guaranteed to sort alphanumerically in order of generation.
/// </remarks>
public class StampGenerator
{
  /// <summary>
  /// All the characters which could be the last character in the stamp.
  /// </summary>
  private static readonly char[] _trailingChars =
  {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
    'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
    'u', 'v', 'w', 'x', 'y'
  };

  /// <summary>
  /// How many valid trailing characters there are.
  /// </summary>
  /// <remarks>Should always equal _trailingChars.Length</remarks>
  public const int TRAILING_RANGE = 25;

  /// <summary>
  /// Maximum length of the stamp. Hard-coded for laziness.
  /// </summary>
  public const int MAX_LENGTH_STAMP = 28;

  /// <summary>
  /// Base portion of the stamp. Will be constant between calls.
  /// </summary>
  /// <remarks>
  /// This is intended to uniquely distinguish between instances.
  /// Default behavior is to generate a minute-accurate timestamp.
  /// </remarks>
  public string StampBase { get; }

  /// <summary>
  /// Number of times this instance has been called.
  /// </summary>
  public int CalledTimes { get; private set; }

  /// <summary>
  /// Maximum number of stamps that can be generated with a given base.
  /// </summary>
  public int MaxCalls { get; }

  /// <summary>
  /// Number of stamps remaining for this instance.
  /// </summary>
  public int RemainingCalls { get { return MaxCalls - CalledTimes; } }

  /// <summary>
  /// Instantiate a StampGenerator with a specific base.
  /// </summary>
  /// <param name="stampBase">Base of stamp.</param>
  /// <param name="calledTimes">
  /// Number of times this base has already been used.
  /// </param>
  public StampGenerator(string stampBase, int calledTimes = 0)
  {
    if (stampBase == null)
    {
      throw new ArgumentNullException("stampBase");
    }
    else if (Regex.IsMatch(stampBase, "[^a-zA-Z_0-9 \\-]"))
    {
      throw new ArgumentException("Invalid characters in Stamp Base.",
                                  "stampBase");
    }
    else if (stampBase.Length >= MAX_LENGTH_STAMP - 1)
    {
      throw new ArgumentException(
        string.Format("Stamp Base too long. (Length {0} out of {1})",
                      stampBase.Length, MAX_LENGTH_STAMP - 1), "stampBase");
    }
    else if (calledTimes < 0)
    {
      throw new ArgumentOutOfRangeException(
        "calledTimes", calledTimes, "calledTimes cannot be negative.");
    }
    else
    {
      int maxCalls = TRAILING_RANGE * (MAX_LENGTH_STAMP - stampBase.Length);
      if (calledTimes >= maxCalls)
      {
        throw new ArgumentOutOfRangeException(
          "calledTimes", calledTimes, string.Format(
            "Called Times too large; max for stem of length {0} is {1}.",
            stampBase.Length, maxCalls));
      }
      else
      {
        StampBase = stampBase;
        CalledTimes = calledTimes;
        MaxCalls = maxCalls;
      }
    }
  }

  /// <summary>
  /// Instantiate a StampGenerator with default base string based on time.
  /// </summary>
  public StampGenerator() : this(DateTime.Now.ToString("yMMddHHmm")) { }

  /// <summary>
  /// Generate a unique stamp.
  /// </summary>
  /// <remarks>
  /// Stamp values are orered like this:
  /// a, b, ... x, y, za, zb, ... zx, zy, zza, zzb, ...
  /// </remarks>
  /// <returns>A unique stamp.</returns>
  public override string ToString()
  {
    int zCount = CalledTimes / TRAILING_RANGE;
    int trailing = CalledTimes % TRAILING_RANGE;
    int length = StampBase.Length + zCount + 1;

    if (length > MAX_LENGTH_STAMP)
    {
      throw new InvalidOperationException(
        "Stamp length overflown! Cannot generate new stamps.");
    }
    else
    {
      CalledTimes = CalledTimes + 1;
      var builder = new StringBuilder(StampBase, length);
      builder.Append('z', zCount);
      builder.Append(_trailingChars[trailing]);
      return builder.ToString();
    }
  }
}

-1

DateTime.Now.Ticksसुरक्षित नहीं है, Guid.NewGuid()बहुत बदसूरत है, अगर आपको कुछ साफ और लगभग सुरक्षित चाहिए ( यह 100% सुरक्षित नहीं है उदाहरण के लिए यदि आप इसे 1ms में 1,000,000 बार कहते हैं ), तो कोशिश करें:

Math.Abs(Guid.NewGuid().GetHashCode())

सुरक्षित रूप से मेरा मतलब है सुरक्षित होना अद्वितीय है जब आप इसे बहुत कम समय में बहुत बार कहते हैं कुछ एमएस समय।


मेरे समाधान downvoter के साथ कोई समस्या है? कृपया मुझे बताओ।
मेहदी देहगानी

GetHashCodeविधि एक रिटर्न int, जो 32-बिट सीमा है, जबकि एक, GUIDएक 128 बिट रेंज है और इतना अधिक अद्वितीय होने की संभावना है। यदि आपको किसी GUIDमूल्य का प्रारूप पसंद नहीं है , तो बस ToString("N")उस पर कॉल करें , जो डैश हटाता है।
4
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.