我已經看到了隨機命名的文件,包括使用C#:什麼是生成唯一文件名的最快方法?
System.IO.Path.GetRandomFileName()
或使用
System.Guid
和附加文件擴展名的若干建議。
我的問題是:什麼是生成唯一文件名的最快方法?
我已經看到了隨機命名的文件,包括使用C#:什麼是生成唯一文件名的最快方法?
System.IO.Path.GetRandomFileName()
或使用
System.Guid
和附加文件擴展名的若干建議。
我的問題是:什麼是生成唯一文件名的最快方法?
GUID將非常快,
,因爲它的實施保證Windows可以在100納秒的時間範圍內生成至少16,384個GUIDS
。 (正如其他人指出的那樣,規範不能保證,只允許,但是,GUID的生成真的很快,真的)。在任何網絡上的任何文件系統上發生衝突的可能性非常低。這是很安全的,儘管最好的做法是始終檢查該文件名是否可用,實際上,您甚至不需要這樣做。
因此,您只查看除保存本身之外的任何I/O操作,並且在測試機器上測試0.2毫秒以生成名稱本身。相當快。
哇!您是否有描述此實施保證的鏈接源? – 2009-10-21 18:19:27
我不相信Windows gaurantees可以在100 nS中產生** 16,384個GUIDS - 只有通過GUID算法產生的值才能確保具有這種分佈級別。此外,使用邏輯,每100-Ns的16k GUIDS將達到每秒1630億GUIDS ...這意味着它只需要一個CPU週期的1/10來生成一個GUID?這沒有多大意義。 – LBushkin 2009-10-21 18:23:31
看到關於GUID唯一性的這個問題http://stackoverflow.com/questions/39771/is-a-guid-unique-100-of-the-time – BlackTigerX 2009-10-21 18:24:13
如果您控制文件所在的目標位置,並且只有一個進程和線程寫入該文件,只需將一些自動遞增數字附加到基本名稱即可。
如果您不控制目標,或者需要多線程實現,請使用GUID。
儘管我幾乎總是使用GUID來解決這個問題,但LBushkin對於性能是正確的。如果你真的想要*每一滴* perf,遞增一個整數並將其轉換爲一個字符串比生成一個Guid並將其轉換爲一個字符串更快......但是隻有當你擁有目錄的控制權時才能工作。 – 2009-10-21 19:02:21
你想System.IO.Path.GetTempFileName()
我不能說,其實無論是最快與否,但它是這樣做的正確方式,這是更重要的。
+1 - 這是最簡單和最好的解決方案。 – Noldorin 2009-10-21 18:32:57
這實際上創建一個文件。我認爲你的意思是System.IO.Path.GetRandomFileName() – 2009-10-21 18:46:41
丹是正確的。它在Windows臨時目錄中創建一個文件。 – adrianbanks 2009-10-21 18:47:38
類似:
file.MoveTo(deletedfilesdir + @"\" + f.Name + **DateTime.Now.ToFileTimeUtc()** + f.Extension);
如果你控制的目錄,你可以基於該lastWriteTime命名文件:
DirectoryInfo info = new DirectoryInfo(directoryPath);
long uniqueKey = info.LastWriteTime.Ticks+1L;
string filename = String.Format("file{0}.txt", key);
但是你要檢查這個代碼的表演:我想建設一個DirectoryInfo不是免費的。
「建立一個DirectoryInfo不會免費」 - 我懷疑你是正確的,特別是如果驅動器/目錄不在計算機本地(網絡驅動器/ NAS/etc) – 2011-03-23 18:07:58
那麼我一直在寫文件系統驅動程序20年,並會說雷克斯是正確的。生成一個GUID要快得多,因爲它比尋找一個唯一的文件名要花費更少的開銷。 GetTempFileName實際上創建了一個文件,這意味着它必須調用整個文件系統驅動程序堆棧(誰知道將會有多少個調用並切換到內核模式。)GetRandomFileName聽起來更快,但我相信GUID調用甚至更快。人們沒有意識到的是,即使測試文件的存在,也需要通過驅動程序堆棧進行完整調用。它實際上導致打開,獲取屬性並關閉(至少3次調用,具體取決於級別)。實際上,它至少需要20次函數調用並轉換到內核模式。 GUIDS對獨特性的保證足以滿足大多數目的。
我的建議是生成名稱並僅在文件不存在時才創建文件。如果是,請拋出異常並捕獲它,然後生成一個新的GUID並重試。那樣,你沒有錯誤的機會,並且可以在夜晚輕鬆入睡。
在旁註中,檢查錯誤是如此的過頭。如果假設錯誤,代碼應該設計爲崩潰,或者捕獲異常並處理它。在異常堆棧上更快地推送和彈出地址,而不是每次檢查每個函數的錯誤。
我希望這種自我迭代功能可以幫助別人生成一個唯一的文件名。
public string getUniqueFileName(int i, string fullpath, string filename)
{
string lstDir = fullpath.Substring(0, fullpath.LastIndexOf('\\'));
string name = Path.GetFileName(fullpath);
string path = fullpath;
if (name != filename)
path = Path.Combine(lstDir, filename);
if (System.IO.File.Exists(path))
{
string ext = Path.GetExtension(name);
name = Path.GetFileNameWithoutExtension(name);
i++;
filename = getUniqueFileName(i, fullpath, name + "_" + i + ext);
}
return filename;
}
這不會創建名爲'file_1_2_3 '? – user5226582 2018-03-02 11:39:00
雖然這會在路徑中生成一個唯一的文件名(雖然它不是線程安全的),但與其他方法相比,它會非常慢,只是簡單地生成一個唯一的文件名而不檢查它是否已經存在。我想這個操作需要快速生成一個唯一的文件名。 Btw你的答案解決了這個問題,它可能對別人有幫助。 – Perrier 2018-03-02 11:51:02
是的,它的確如此。我的期望是增加相同的數字,但它變成了連接。需要修改代碼以使其按預期工作。如果有人更正我的代碼,會很感激。提前致謝。 – Bikuz 2018-03-02 11:52:08
爲什麼你不使用一種方法*速度夠快*? – Joren 2009-10-21 18:14:28
一個很好的問題。答案是,我試圖從這個文件系統密集型應用程序中擠出每盎司的性能。 – 2009-10-21 18:17:17
這真的取決於你的意思是「獨一無二」 - 它是否具有通用的獨特性,在文件系統中是獨一無二的,在同一個程序的不同線程中是唯一的......? – 2009-10-21 18:17:25