라우
6월 17, 2024, 11:59오전
1
안녕하세요
C#으로 Windows 환경에서 파일을 마스킹 처리해주는 프로그램을 만들고 있습니다.
사용자가 압축 파일을 업로드하면 Temp Directory에 압축 해제한 뒤 파일을 편집하고 있는데, 내부 Depth가 깊은 압축 파일의 경우 Windows의 MAX_PATH로 인해 Exception이 발생합니다.
(Temp Directory : 사용자 폴더\Local\ProgramData~ 로 해당 경로만으로도 MAX_PATH의 1/2이 사용됩니다.)
이를 해결하기 위해 2가지 시도를 해봤는데 잘 되지 않아 질문 드립니다.
접두사로 "\?"를 Path앞에 붙이면 문제 없이 폴더 및 파일이 생성된다고 하여 테스트를 해보았습니다.
string prefix = @"\\?\";
string dirPath = prefix + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PostDirectory");
Directory.CreateDirectory(dirPath);
prefix를 안붙이면 "System.IO.PathTooLongException 발생
prefix를 붙이면 “System.IO.IOException: '파일 이름, 디렉터리 이름 또는 볼륨 레이블 구문이 잘못되었습니다.” 가 발생
테스트 코드가 잘못된걸까요?
AlphaFS 패키지를 사용해서도 테스트를 해봤습니다.
Windows API 사용해서 MAX_PATH 우회는 가능하지만 tarArchive.ExtractContents 메서드처럼 .NET의 기능을 사용하는 것까지는 대응이 안되네요.
긴 경로 하위에 압축해제하는 방법이 있을까요?
많은 조언 부탁드립니다.
혹시 운영체제나 재현 코드를 알 수 있을까요? 제 경우에 다음과 같이 테스트를 해봤는데,
string tempPath = @"C:\temp";
for (int i = 0; i < 10; i++)
{
tempPath = Path.Combine(tempPath, "longpathtest_01234567890123456789012345678901234567890123456789");
Directory.CreateDirectory(tempPath);
}
Console.WriteLine(tempPath.Length);
string filePath = Path.Combine(tempPath, "test.txt");
File.WriteAllText(filePath, "test");
using ZipArchive zipArchive = ZipFile.Open("ConsoleApp1.zip", ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(tempPath, true);
잘 동작합니다. Windows 7하고 11에서 .NET 5로 테스트해봤습니다.
3개의 좋아요
라우
6월 17, 2024, 11:58오후
3
Windows10입니다.
MAX_PATH는 260자를 넘어야 발생하기 때문에 아래와 같이 테스트 해봤습니다.
string prefix = @"\\?\";
string postPath = "";
for(int i=0; i<280; i++)
{
postPath += "a";
}
string dirPath = prefix + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), postPath);
Directory.CreateDirectory(dirPath);
음… 그냥 전체 경로를 해시로 바꿔서 작업하면 안 되려나요? ㅎㅎㅎ
2개의 좋아요
문서상으로는, 단일 디렉터리의 이름은 여전히 255를 넘을 수 없습니다. 이에 대해서는 다음의 문서에서,
CreateDirectory function (winbase.h) - Win32 apps | Microsoft Learn
아래와 같이 명시돼 있습니다.
The 255 character limit per path segment still applies.
4개의 좋아요
tkm
6월 18, 2024, 3:36오전
6
.NET 프레임워크에서 .NET 6 이상으로 마이그레이션 가능하다면 마이그레이션 하고.
아니면 해당 로직만 별도 실행파일로 분리하세요
또 다른 편법으로는 심볼릭 링크를 통한 경로 단축 등이 있겠네요
3개의 좋아요
LongPathsEnabled를 사용해 보셨을까요?
2개의 좋아요
사용자 PC의 Windows 버전을 특정할 수 없어 LongPathsEnabled는 사용하지 못하고, Path 길이 제한을 해제할 방법이 없을 것 같아 사양을 변경하기로 했습니다.
다들 조언해주셔서 감사합니다!!
2개의 좋아요