C# 将(n)附加到文件名(不使用system.io.file)以确保名称唯一
我有一个类,它保存文件名和文件数据:C# 将(n)附加到文件名(不使用system.io.file)以确保名称唯一,c#,loops,collections,zipfile,C#,Loops,Collections,Zipfile,我有一个类,它保存文件名和文件数据: public class FileMeta { public string FileName { get; set; } public byte[] FileData { get; set; } } 我有一个通过异步下载操作填充此类集合的方法(文件不是来自本地文件系统): 关于如何在文件系统中实现这一点,有许多示例,但不是使用简单的对象集合。(例如,使用System.IO.File.Exists) 在对象集合中循环并返回一组唯一的文件名的最
public class FileMeta
{
public string FileName { get; set; }
public byte[] FileData { get; set; }
}
我有一个通过异步下载操作填充此类集合的方法(文件不是来自本地文件系统):
关于如何在文件系统中实现这一点,有许多示例,但不是使用简单的对象集合。(例如,使用System.IO.File.Exists
)
在对象集合中循环并返回一组唯一的文件名的最佳方法是什么
我已经走了多远
private List<FileMeta> EnsureUniqueFileNames(IEnumerable<FileMeta> fileMetas)
{
var returnList = new List<FileMeta>();
foreach (var file in fileMetas)
{
while (DoesFileNameExist(file.FileName, returnList))
{
//Append (n) in sequence until match is not found?
}
}
return returnList;
}
private bool DoesFileNameExist(string fileName, IEnumerable<FileMeta> fileMeta)
{
var fileNames = fileMeta.Select(file => file.FileName).ToList();
return fileNames.Contains(fileName);
}
private List确保文件名(IEnumerable fileMetas)
{
var returnList=新列表();
foreach(fileMetas中的var文件)
{
while(DoesFileNameExist(file.FileName,returnList))
{
//是否按顺序追加(n),直到找不到匹配项?
}
}
退货清单;
}
私有bool DoesFileNameExist(字符串文件名,IEnumerable fileMeta)
{
var fileNames=fileMeta.Select(file=>file.FileName.ToList();
返回文件名。包含(文件名);
}
您可以尝试以下方法来增加文件名:
private List<FileMeta> EnsureUniqueFileNames(IEnumerable<FileMeta> fileMetas)
{
var returnedList = new List<FileMeta>();
foreach (var file in fileMetas)
{
int count = 0;
string originalFileName = file.FileName;
while (returnedList.Any(fileMeta => fileMeta.FileName.Equals(file.FileName,
StringComparison.OrdinalIgnoreCase))
{
string fileNameOnly = Path.GetFileNameWithoutExtension(originalFileName);
string extension = Path.GetExtension(file.FileName);
file.FileName = string.Format("{0}({1}){2}", fileNameOnly, count, extension);
count++;
}
returnList.Add(file);
}
return returnList;
}
我将返回类型设置为
FileMeta[]
而不是List
,因为它是一个固定大小的返回,并且减少了对返回数组调用ToList
的需要。我还添加了Async
postfix,以遵循TAP指南。什么是“不使用System.IO”?您正在使用System.IO.Path
@TimSchmelter Good Point。我已经看到了一些使用绑定到文件系统中的方法的示例,它们使用了我在这里无法使用的system.IO.file.Exists
。我会纠正的。编辑:编辑问题以获得更多信息specific@clcto你好。是的,正在下载的文件在其文件夹中是唯一的,但我们正在跨文件夹访问。所以如果我抓取文件http://file.com/folder1/sample.pdf
和http://file.com/folder2/sample.pdf
,它们在主机位置上是唯一的。但是在将它们下载到FileMeta
对象之后,它们只是sample.pdf
,我们有一个名称冲突。这不应该被关闭。这是一个明确而完整的问题。只是标记它以引起注意。基本技术是stringnewname;do{index++;newName=string.Format(“文件({0}).txt”,index);}而(nameisuse(newName))代码>那是个坏蛋。不将HttpClient封装在using语句中有任何危险吗?这是Glenn Block的一句话,他目前在Microsoft Azure工作(这来自使用ASP.NET设计可演化Web API):虽然HttpClient确实间接实现IDisposable接口,但HttpClient的标准用法不是在每次请求后都处理它。只要应用程序需要发出HTTP请求,HttpClient对象就会一直存在。如果您看到它在将来会引起任何麻烦,您可以随时进行重构。
private List<FileMeta> EnsureUniqueFileNames(IEnumerable<FileMeta> fileMetas)
{
var returnList = new List<FileMeta>();
foreach (var file in fileMetas)
{
while (DoesFileNameExist(file.FileName, returnList))
{
//Append (n) in sequence until match is not found?
}
}
return returnList;
}
private bool DoesFileNameExist(string fileName, IEnumerable<FileMeta> fileMeta)
{
var fileNames = fileMeta.Select(file => file.FileName).ToList();
return fileNames.Contains(fileName);
}
private List<FileMeta> EnsureUniqueFileNames(IEnumerable<FileMeta> fileMetas)
{
var returnedList = new List<FileMeta>();
foreach (var file in fileMetas)
{
int count = 0;
string originalFileName = file.FileName;
while (returnedList.Any(fileMeta => fileMeta.FileName.Equals(file.FileName,
StringComparison.OrdinalIgnoreCase))
{
string fileNameOnly = Path.GetFileNameWithoutExtension(originalFileName);
string extension = Path.GetExtension(file.FileName);
file.FileName = string.Format("{0}({1}){2}", fileNameOnly, count, extension);
count++;
}
returnList.Add(file);
}
return returnList;
}
private Task<FileMeta[]> ReturnFileDataAsync(IEnumerable<string> urls)
{
var client = new HttpClient();
return Task.WhenAll(urls.Select(async url => new FileMeta
{
FileName = Path.GetFileName(url),
FileData = await client.GetByteArrayAsync(url),
}));
}