하드 드라이브에 저장할 파일의 고유 이름을 생성하는 알고리즘을 구현했습니다. 내가 추가하고 있습니다 DateTime
: Hours, Minutes, Second and Milliseconds 하지만 한 번에 여러 파일을 업로드하기 때문에 여전히 중복 된 파일 이름을 생성합니다.
파일이 하드 드라이브에 저장되도록 고유 한 이름을 생성하여 2 개의 파일이 동일하지 않도록하는 가장 좋은 솔루션은 무엇입니까?
답변
가독성이 중요하지 않으면 GUID를 사용하십시오 .
예 :
var myUniqueFileName = string.Format(@"{0}.txt", Guid.NewGuid());
또는 더 짧은 :
var myUniqueFileName = $@"{Guid.NewGuid()}.txt";
내 프로그램에서 읽을 수있는 이름 ( “Image1.png”… “Image10.png”)을 생성하기 위해 예를 들어 10 번 시도하는 경우가 있는데 (파일이 이미 있기 때문에) 실패하면 GUID로 돌아갑니다.
최신 정보:
최근 DateTime.Now.Ticks
에는 GUID 대신 사용 했습니다.
var myUniqueFileName = string.Format(@"{0}.txt", DateTime.Now.Ticks);
또는
var myUniqueFileName = $@"{DateTime.Now.Ticks}.txt";
나에게 이점은 이것이 GUID에 비해 더 짧고 “더욱보기 좋은”파일 이름을 생성한다는 것입니다.
경우에 따라 (예 : 매우 짧은 시간에 많은 임의의 이름을 생성 할 때) 고유하지 않은 값을 만들 수 있습니다 .
다른 컴퓨터로 파일을 전송할 때에도 파일 이름이 고유한지 확인하려면 GUID를 고수하십시오.
답변
답변
System.IO.Path.GetRandomFileName()
답변
파일 이름의 가독성이 중요하지 않은 경우 많은 사람들이 제안한 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 자입니다.
답변
다음은 제공된 원본을 기준으로 읽을 수있는 고유 한 파일 이름을 반환하는 알고리즘입니다. 원본 파일이 있으면 존재하지 않는 파일을 찾을 때까지 파일 이름에 색인을 추가하려고합니다. 충돌을 확인하기 위해 기존 파일 이름을 HashSet으로 읽어들이므로 매우 빠르며 (내 컴퓨터에서 초당 수백 개의 파일 이름) 스레드 안전하고 경쟁 조건으로 고통받지 않습니다.
예를 들어, 전달하면 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();
}
}
답변
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)) : "");
}
답변
- 일반적인 프로세스에 따라 타임 스탬프가 지정된 파일 이름을 만듭니다.
- 파일 이름이 있는지 확인하십시오
- 거짓-파일 저장
- True-카운터에 추가 문자를 파일에 추가
- 2 단계로 이동