Svi*_*ish 45 c# filenames unique
我想创建一个方法,它将文件名作为a string或a FileInfo,如果文件存在,则将增加的数字添加到文件名.但是不能完全理解如何以一种好的方式做到这一点.
例如,如果我有这个FileInfo
var file = new FileInfo(@"C:\file.ext");
Run Code Online (Sandbox Code Playgroud)
我想的方法给我一个新的FileInfo与C:\文件1.ext如果\ file.ext:C 存在,C:\文件2.ext如果C:\文件1.ext存在等.像这样的东西:
public FileInfo MakeUnique(FileInfo fileInfo)
{
if(fileInfo == null)
throw new ArgumentNullException("fileInfo");
if(!fileInfo.Exists)
return fileInfo;
// Somehow construct new filename from the one we have, test it,
// then do it again if necessary.
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 50
public FileInfo MakeUnique(string path)
{
string dir = Path.GetDirectoryName(path);
string fileName = Path.GetFileNameWithoutExtension(path);
string fileExt = Path.GetExtension(path);
for (int i = 1; ;++i) {
if (!File.Exists(path))
return new FileInfo(path);
path = Path.Combine(dir, fileName + " " + i + fileExt);
}
}
Run Code Online (Sandbox Code Playgroud)
显然,这很容易受到其他答案中提到的竞争条件的影响.
Svi*_*ish 30
这里有很多好建议.最后我用书面的方法马克在回答不同的问题.重新格式化了一点,并添加了另一种方法,使其更容易"从外部"使用.结果如下:
private static string numberPattern = " ({0})";
public static string NextAvailableFilename(string path)
{
// Short-cut if already available
if (!File.Exists(path))
return path;
// If path has extension then insert the number pattern just before the extension and return next filename
if (Path.HasExtension(path))
return GetNextFilename(path.Insert(path.LastIndexOf(Path.GetExtension(path)), numberPattern));
// Otherwise just append the pattern to the path and return next filename
return GetNextFilename(path + numberPattern);
}
private static string GetNextFilename(string pattern)
{
string tmp = string.Format(pattern, 1);
if (tmp == pattern)
throw new ArgumentException("The pattern must include an index place-holder", "pattern");
if (!File.Exists(tmp))
return tmp; // short-circuit if no matches
int min = 1, max = 2; // min is inclusive, max is exclusive/untested
while (File.Exists(string.Format(pattern, max)))
{
min = max;
max *= 2;
}
while (max != min + 1)
{
int pivot = (max + min) / 2;
if (File.Exists(string.Format(pattern, pivot)))
min = pivot;
else
max = pivot;
}
return string.Format(pattern, max);
}
Run Code Online (Sandbox Code Playgroud)
到目前为止只进行了部分测试,但如果发现任何错误,将会更新.(Marc的代码效果很好!)如果您发现任何问题,请评论或编辑或者:)
Pie*_*let 18
不漂亮,但我有一段时间了:
private string getNextFileName(string fileName)
{
string extension = Path.GetExtension(fileName);
int i = 0;
while (File.Exists(fileName))
{
if (i == 0)
fileName = fileName.Replace(extension, "(" + ++i + ")" + extension);
else
fileName = fileName.Replace("(" + i + ")" + extension, "(" + ++i + ")" + extension);
}
return fileName;
}
Run Code Online (Sandbox Code Playgroud)
假设文件已经存在:
调用getNextFileName("File.txt")将返回"File(3).txt".
不是最有效的,因为它不使用二进制搜索,但对于小文件计数应该没问题.并且它不考虑竞争条件......
mga*_*911 12
如果检查文件是否存在太难,您可以随时在文件名中添加日期和时间以使其唯一:
FileName.YYYYMMDD.HHMMSS
如果有必要,甚至可以添加毫秒.
如果格式不打扰你,那么你可以打电话:
try{
string tempFile=System.IO.Path.GetTempFileName();
string file=System.IO.Path.GetFileName(tempFile);
//use file
System.IO.File.Delete(tempFile);
}catch(IOException ioe){
//handle
}catch(FileIOPermission fp){
//handle
}
Run Code Online (Sandbox Code Playgroud)
PS: - 请在使用之前在msdn上阅读更多相关信息.