我有一个将文件从一个目录移动到另一个目录的应用程序,但有时会发生冲突,并且该文件已经存在于目标目录中。
当发生这种情况时,我想用不同的名称移动文件 - 例如如果文件名为test.txt
,我想将其命名为test.txt.1
。没关系,但如果文件又是test.txt
,我下次怎么办呢,但在目标文件夹中我们同时有test.txt
和test.txt.1
。
我的问题是我无法找到最后创建的文件,以便我可以读取其索引并将其递增1.任何建议?
string sourcePath = "C:\\Files\\test.txt";
string filename = Path.GetFileName(sourcePath);
string pathTo = "C:\\Files\\test\\" + filename;
try
{
var fileInfo = new FileInfo(sourcePath);
fileInfo.MoveTo(pathTo);
}
catch (IOException ex)
{
var fileInfo = new FileInfo(sourcePath);
var file = Directory.GetFiles(pathTo, filename+".1").FirstOrDefault();
if (file == null)
{
fileInfo.MoveTo(pathTo+".1");
}
else
{
//find the old file, read it's last index and increment it with 1
}
}
答案 0 :(得分:4)
你可以使用这样的函数..
void MoveFileToPath(string sourceFilePath,string destinationDirectory)
{
int index = 1;
string fileName = Path.GetFileName(sourceFilePath);
string destPath = destinationDirectory+fileName;
while(File.Exists(destPath))
{
destPath = string.Format("{0}{1}.{2}",destinationDirectory,fileName,index);
index++;
}
var fileInfo = new FileInfo(sourceFilePath);
Console.WriteLine("Test:"+destPath);
fileInfo.MoveTo(destPath);
}
答案 1 :(得分:2)
Func<int, string> getFileName= delegate(int i)
{
return string.Format("{0}/{1}{2}.{3}", dir, filenameWithouExt, i, ext);
};
int i = 0;
while(File.Exists(getFileName(i)))
{
i++;
}
fileInfo.MoveTo(getFileName(i));
这取决于你有多少文件。如果您有大量文件,可以更快地使用它:
int i = 0;
while(File.Exists(getFileName(i)))
{
i+=100;
}
i-=90;
while(File.Exists(getFileName(i)))
{
i+=10;
}
i-=9;
while(File.Exists(getFileName(i)))
{
i+=1;
}
答案 2 :(得分:2)
我稍微重写了你的代码,因为你是针对异常进行编程的,这是我真的不鼓励的。
首先,它检查原始文件是否已存在。
然后,作为原始代码,它尝试使用.1索引器创建文件。如果已经存在,则会遍历目录以查找具有相同文件名的所有文件。
最后,它会找到最后使用的索引并将其递增一个。
请注意,您也可以跳过else语句中的第一个if语句,因为它仍然会搜索最后使用的索引;如果不存在,则lastIndex将保持为0(有一个增量,因此它将使用1作为新文件的索引)。
var fileInfo = new FileInfo(sourcePath);
// Check if the file already exists.
if (!fileInfo.Exists)
fileInfo.MoveTo(pathTo);
else
{
var file = Directory.GetFiles(pathTo, filename + ".1").FirstOrDefault();
if (file == null)
{
fileInfo.MoveTo(pathTo + ".1");
}
else
{
// Get all files with the same name.
string[] getSourceFileNames = Directory.GetFiles(Path.GetDirectoryName(pathTo)).Where(s => s.Contains(filename)).ToArray();
// Retrieve the last index.
int lastIndex = 0;
foreach (string s in getSourceFileNames)
{
int currentIndex = 0;
int.TryParse(s.Split('.').LastOrDefault(), out currentIndex);
if (currentIndex > lastIndex)
lastIndex = currentIndex;
}
// Do something with the last index.
lastIndex++;
fileInfo.MoveTo(pathTo + lastIndex);
}
}
答案 3 :(得分:2)
我更愿意编写一个方法来返回文件的下一个索引并删除try-catch块:
string sourcePath = "C:\\Files\\test.txt";
string filename = Path.GetFileName(sourcePath);
string pathTo = "C:\\Files\\test\\"; // the destination file name would be appended later
var fileInfo = new FileInfo(sourcePath);
if (!fileInfo.Exists)
{
fileInfo.MoveTo(pathTo);
}
else
{
// Get all files by mask "test.txt.*"
var files = Directory.GetFiles(pathTo, string.Format("{0}.*", filename)).ToArray();
var newExtension = GetNewFileExtension(files); // will return .1, .2, ... .N
fileInfo.MoveTo(Path.Combine(pathTo, string.Format("{0}{1}", filename, newExtension)));
}
获取新索引的新方法:
public static string GetNewFileExtension(string[] fileNames)
{
int maxIndex = 0;
foreach (var fileName in fileNames)
{
// get the file extension and remove the "."
string extension = Path.GetExtension(fileName).Substring(1);
int parsedIndex;
// try to parse the file index and do a one pass max element search
if(int.TryParse(extension, out parsedIndex))
{
if(parsedIndex > maxIndex)
{
maxIndex = parsedIndex;
}
}
}
// increment max index by 1
return string.Format(".{0}", maxIndex + 1);
}