부적절한 순간 에이 문제에 대해 몇 번 나왔습니다.
- 딥 패스로 오픈 소스 Java 프로젝트 작업
- 소스 제어에 Deep Fitnesse 위키 트리 저장
- Bazaar를 사용하여 소스 제어 트리를 가져 오는 중에 오류가 발생했습니다.
이 한계가 존재하는 이유는 무엇입니까?
왜 아직 제거되지 않았습니까?
경로 제한에 어떻게 대처합니까? 그리고 아니요, Linux 또는 Mac OS X로 전환하는 것이이 질문에 대한 올바른 대답은 아닙니다.)
부적절한 순간 에이 문제에 대해 몇 번 나왔습니다.
이 한계가 존재하는 이유는 무엇입니까?
왜 아직 제거되지 않았습니까?
경로 제한에 어떻게 대처합니까? 그리고 아니요, Linux 또는 Mac OS X로 전환하는 것이이 질문에 대한 올바른 대답은 아닙니다.)
답변:
이 기사 인용하기 https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
최대 경로 길이 제한
Windows API에서 (다음 단락에서 설명하는 일부 예외) 경로의 최대 길이는 MAX_PATH 이며 260 자로 정의됩니다. 로컬 경로는 드라이브 문자, 콜론, 백 슬래시, 백 슬래시로 구분 된 이름 구성 요소 및 종료 널 문자의 순서로 구성됩니다. 예를 들어, 드라이브 D의 최대 경로는 "D : \ some 256 자 경로 문자열 <NUL>"입니다. 여기서 "<NUL>"은 현재 시스템 코드 페이지의 보이지 않는 종료 널 문자를 나타냅니다. (<> 문자는 시각적 선명도를 위해 사용되며 유효한 경로 문자열의 일부가 될 수 없습니다.)
이제 우리는 그것이 1 + 2 + 256 + 1 또는 [drive] [: \] [path] [null] = 260임을 알 수 있습니다. 256은 DOS 시절의 적당한 고정 문자열 길이라고 가정 할 수 있습니다. DOS API로 돌아가서 시스템이 드라이브 당 현재 경로를 추적했으며 최대 드라이브 수 (및 현재 디렉토리) 가 26 개 (기호가있는 32 개 ) 인 것을 알 수 있습니다.
INT 0x21 AH = 0x47은 "이 함수는 드라이브 문자와 초기 백 슬래시없이 경로 설명을 반환합니다."라고 말합니다. 따라서 시스템이 CWD를 쌍 (드라이브, 경로)으로 저장하고 드라이브를 지정하여 경로를 요청한다는 것을 알 수 있습니다 (1 = A, 2 = B,…). 0을 지정하면 경로를 가정합니다. INT 0x21 AH = 0x15 AL = 0x19에 의해 반환 된 드라이브. 이제 4 바이트가 경로 문자열에 저장되지 않기 때문에 256이 아닌 260 인 이유를 알 수 있습니다.
640K가 충분한 RAM이기 때문에 256 바이트 경로 문자열이 필요한 이유는 무엇입니까?
NTFS 파일 시스템이 최대 32k 문자의 경로를 지원하기 때문에 이것은 사실이 아닙니다. win32 api 및 " \\?\
"접두어를 사용하여 260자를 초과하는 경로를 사용할 수 있습니다.
.Net BCL 팀 블로그 에서 긴 경로에 대한 자세한 설명 .
작은 발췌문은 긴 경로의 문제를 강조합니다.
또 다른 문제는 긴 경로 지원을 제공함으로써 발생하는 일관되지 않은 동작입니다.
\\?\
접두사가있는 긴 경로 는 대부분의 파일 관련 Windows API에서 사용할 수 있지만 일부 Windows API에서는 사용할 수 없습니다. 예를 들어, 파일 이름이 MAX_PATH보다 길면 모듈을 호출 프로세스의 주소에 매핑하는 LoadLibrary가 실패합니다. 따라서 MoveFile을 사용하면 경로가 260자를 초과하는 위치로 DLL을 이동할 수 있지만 DLL을로드하려고하면 실패합니다. Windows API 전체에 유사한 예제가 있습니다. 일부 해결 방법이 있지만 상황에 따라 다릅니다.
문제는 여전히 제한이 존재하는 이유 입니다. 확실히 현대 Windows는 MAX_PATH
더 긴 경로를 허용하기 위해 측면을 늘릴 수 있습니다 . 제한이 제거되지 않은 이유는 무엇입니까?
API 계약을 통해 Windows는 표준 파일 API가 260
문자 보다 긴 경로를 반환하지 않도록 모든 응용 프로그램을 보장했습니다 .
다음 올바른 코드를 고려하십시오 .
WIN32_FIND_DATA findData;
FindFirstFile("C:\Contoso\*", ref findData);
Windows 는 내 프로그램이 내 WIN32_FIND_DATA
구조를 채우도록 보증 했습니다 .
WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
//...
TCHAR cFileName[MAX_PATH];
//..
}
내 응용 프로그램은 constant의 값을 선언 MAX_PATH
하지 않았으며 Windows API는 그랬습니다. 내 응용 프로그램은 그 정의 된 값을 사용했습니다.
내 구조가 올바르게 정의되었으며 592
총 바이트 수만 할당 합니다. 즉, 260
문자 보다 작은 파일 이름 만받을 수 있습니다. Windows 는 응용 프로그램을 올바르게 작성하면 앞으로도 계속 응용 프로그램이 작동 할 것이라고 약속했습니다.
Windows가 260
문자 보다 긴 파일 이름을 허용하는 경우 기존 응용 프로그램 (올바른 API를 올바르게 사용)이 실패합니다.
Microsoft가 MAX_PATH
상수 를 변경하도록 요구하는 사람은 먼저 기존 응용 프로그램이 실패하지 않도록해야합니다. 예를 들어, 나는 여전히 Windows 3.11에서 실행되도록 작성된 Windows 응용 프로그램을 소유하고 사용합니다. 여전히 64 비트 Windows 10에서 실행됩니다. 이것이 이전 버전과의 호환성을 제공합니다.
Microsoft 는 전체 32,768 경로 이름을 사용하는 방법을 만들었습니다. 그러나 그들은 그것을하기 위해 새로운 API 계약을 만들어야했습니다. 우선, 셸 API 를 사용하여 파일을 열거해야합니다 (모든 파일이 하드 드라이브 나 네트워크 공유에있는 것은 아님).
그러나 기존 사용자 응용 프로그램을 중단하지 않아도됩니다. 대부분의 응용 프로그램은 파일 작업에 쉘 API를 사용 하지 않습니다 . 모든 사람은 호출 FindFirstFile
/ FindNextFile
하루를 호출합니다.
Windows 10에서 . 레지스트리 키를 수정 하여 제한 을 제거 할 수 있습니다 .
팁 Windows 10 버전 1607부터 일반적인 Win32 파일 및 디렉토리 기능에서 MAX_PATH 제한이 제거되었습니다. 그러나 새 동작을 선택해야합니다.
레지스트리 키를 사용하면 새로운 긴 경로 동작을 활성화하거나 비활성화 할 수 있습니다. 긴 경로 동작을 사용하려면 레지스트리 키를
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled
(유형 :)로 설정하십시오REG_DWORD
. 키 값은 영향을받는 Win32 파일 또는 디렉토리 기능을 처음 호출 한 후 시스템 (프로세스 당)에 의해 캐시됩니다 (목록은 다음과 같습니다). 프로세스 수명 동안 레지스트리 키가 다시로드되지 않습니다. 시스템의 모든 앱이 키 값을 인식하려면 키를 설정하기 전에 일부 프로세스가 시작되었을 수 있으므로 재부팅이 필요할 수 있습니다. 레지스트리 키는에서 그룹 정책을 통해 제어 할 수도 있습니다Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths
. 매니페스트를 통해 앱마다 새로운 긴 경로 동작을 활성화 할 수도 있습니다.<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>
폴더를 드라이브로 마운트 할 수 있습니다. 명령 행에서 경로가있는 경우 다음을 사용하여 경로 C:\path\to\long\folder
를 드라이브 문자에 맵핑 할 수 있습니다 X:
.
subst x: \path\to\long\folder
subst
로컬 세션 / 계정입니다. '시스템 전체'로 만드는 방법에 대해서는 superuser.com/questions/29072/… 를 참조하십시오
경로 제한에 대처하는 한 가지 방법은 기호 링크로 경로 항목을 줄이는 것입니다.
예를 들면 다음과 같습니다.
C:\p
긴 경로에 대한 짧은 링크를 유지하기 위한 디렉토리를 만듭니다.mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
C:\p\foo
긴 경로 대신 경로에 추가/j
옵션은 로컬 볼륨 장치 또는 로컬 볼륨의 경로 (예 : Unix 바인드 마운트)에 대한 접합 마운트 지점을 만듭니다. 심볼릭 링크를 만들지 않습니다. 정션 마운트 지점은 항상 서버에서 평가되고 로컬 장치를 대상으로해야하는 반면, 심볼릭 링크는 클라이언트에서 평가되며 원격 경로를 대상으로 할 수 있으므로 (정책에서 허용하는 경우) 중요한 차이점입니다. subst.exe 드라이브 (예 :)와 같이 DefineDosDeviceW
정션 대상은 일반적으로 약 4K 자로 제한됩니다. 실제로 8K 문자이며 대체 경로와 표시 경로 사이에서 균등하게 분할됩니다.
PowerShell을 사용하여 긴 경로 이름을 활성화 할 수 있습니다.
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1
다른 버전은 Computer Configuration
/ Administrative Templates
/ System
/ 에서 그룹 정책을 사용하는 것입니다 Filesystem
.
이것이 여전히 존재 하는 이유에 대해-MS는 우선 순위를 고려하지 않으며 (적어도이 경우) OS를 향상시키는 것보다 하위 호환성을 중요하게 생각합니다.
내가 사용하는 해결 방법은 사람이 읽을 수있는 표준 버전 대신 경로의 디렉토리에 "짧은 이름"을 사용하는 것입니다. 그래서 예 를 위해 C:\Program Files\
내가 사용하는 것이 C:\PROGRA~1\
사용하여 짧은 이름 등가물을 찾을 수 있습니다 당신을 dir /x
.
PATH
하여로 전달하십시오 SearchPathW
. 런타임 라이브러리는 어쨌든 NT에 대한 "\\? \"장치 경로를 생성하기 때문에 효율적입니다. 최신 파일 시스템의 경우 보안이 없기 때문에 휴대용 응용 프로그램 이외의 exFAT 볼륨에 소프트웨어가 설치되어 있지 않을 수도 있지만 ReFS를 배제하지는 않을 것입니다. 사용자는 편의성, 공간 또는 성능상의 이유로 비표준 위치에 프로그램을 설치합니다.
Windows에서 경로 크기 제한에 대처하는 방법에 대해 7zip 을 사용 하여 경로 길이에 민감한 파일을 압축 (및 압축 풀기)하는 것은 실용적인 해결 방법처럼 보입니다. 나는 여러 IDE 설치 (이클립스 플러그인 경로, yikes!) 및 자동 생성 된 문서 더미를 전송하는 데 사용했으며 지금까지 단일 문제는 없었습니다.
Windows (기술적 PoV)에서 설정 한 260 자 제한을 어떻게 피할 수 있는지 확실하지 않지만 잘 작동합니다!
SourceForge 페이지에 대한 자세한 내용은 여기를 참조 하십시오 .
"NTFS는 실제로 최대 32,000 자 길이의 경로 이름을 지원할 수 있습니다."
7-zip은 또한 그러한 긴 이름을 지원합니다.
그러나 SFX 코드에서는 비활성화되어 있습니다. 일부 사용자는 작업 방법을 이해하지 못하기 때문에 긴 경로를 좋아하지 않습니다. 그래서 SFX 코드에서 비활성화했습니다.
및 출시 정보 :
9.32 알파 2013-12-01
- 260 자보다 긴 파일 경로 이름에 대한 지원이 향상되었습니다.
4.44 베타 2007-01-20
- 7-Zip은 이제 260 자보다 긴 파일 경로 이름을 지원합니다.
중요 참고 : 이 기능이 제대로 작동하려면 파일을 원하는 폴더로 드래그 앤 드롭하지 않고 7zip "추출"대화 상자에서 직접 대상 경로를 지정해야 합니다. 그렇지 않으면 "Temp"폴더가 임시 캐시로 사용되며 Windows 탐색기가 파일을 "최종 휴게소"로 이동하기 시작하면 동일한 260 자 제한으로 바운스됩니다. 자세한 내용은 이 질문에 대한 답변 을 참조하십시오.
그것은 어떤 이유로 든 기본값이지만이 레지스트리 키로 쉽게 무시할 수 있습니다.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
참조 : https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/
이에 대처하는 또 다른 방법은 파일로 무엇을 하려는지에 따라 Cygwin을 사용하는 것입니다 (예 : Cygwin 명령이 사용자의 요구에 적합한 경우)
예를 들어 Windows 탐색기에서도 할 수없는 파일을 복사, 이동 또는 이름을 바꿀 수 있습니다. 또는 md5sum, grep, gzip 등과 같은 내용을 처리하십시오.
또한 코딩하는 프로그램의 경우 Cygwin DLL에 링크 할 수 있으며 긴 경로를 사용할 수 있습니다 (테스트하지는 않았습니다)