Mengapa batas panjang jalur 260 karakter ada di Windows?

390

Saya telah menghadapi masalah ini beberapa kali pada saat yang tidak tepat:

  • Mencoba untuk bekerja pada proyek Java open source dengan jalur yang dalam
  • Menyimpan pohon wiki Fitnesse yang dalam di kontrol sumber
  • Galat mencoba menggunakan Bazaar untuk mengimpor pohon kendali sumber saya

Mengapa batas ini ada?

Mengapa belum dihapus?

Bagaimana Anda mengatasi batas jalur? Dan tidak, beralih ke Linux atau Mac OS X bukan jawaban yang valid untuk pertanyaan ini;)

Jeffrey Cameron
sumber
8
@ Artelius: Sebenarnya, Windows (setidaknya dari Win2K dan seterusnya) mendukung titik persimpangan ( en.wikipedia.org/wiki/NTFS_junction_point ), dan Vista selanjutnya mendukung tautan Symbolic NT ( en.wikipedia.org/wiki/NTFS_symbolic_link ). Bagaimanapun, sementara symlink dapat membantu membuat jalur yang lebih panjang / bersarang lebih ramah, saya tidak bisa memikirkan bagaimana symlink akan membantu jika Anda mencapai batas panjang lintasan.
Ashutosh Mehra
8
Sekalipun batas ini tidak ada, selalu ada banyak batasan lain, dan masing-masing dari mereka mungkin mengganggu pada beberapa titik. Intinya adalah mengapa batas ini sangat rendah? Setelah era 8.3, dan dengan perangkat keras berukuran mega / giga, jalur sekarang harus berupa string yang dialokasikan secara dinamis dengan ukuran yang hampir tidak terbatas.
Roland
12
Microsoft akhirnya mengatasi masalah ini, di Windows 10 Build 14352.
Warren P
3
Ya, dan sepertinya Anda harus memodifikasi manifes aplikasi untuk menjadikannya jalur yang panjang.
Warren P
3
@ PatrickSzalapski sayangnya itu diperbaiki visualstudio.uservoice.com/forums/121579-visual-studio/…
phuclv

Jawaban:

231

Mengutip artikel ini https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

Batasan Panjang Jalur Maksimum

Di Windows API (dengan beberapa pengecualian yang dibahas dalam paragraf berikut), panjang maksimum untuk jalur adalah MAX_PATH , yang didefinisikan sebagai 260 karakter. Jalur lokal disusun dalam urutan berikut: huruf kandar, titik dua, garis miring terbalik, komponen nama yang dipisahkan oleh garis miring terbalik, dan karakter nol yang diakhiri. Misalnya, jalur maksimum pada drive D adalah "D: \ beberapa string jalur 256-karakter <NUL>" di mana "<NUL>" mewakili karakter null penghentian yang tidak terlihat untuk codepage sistem saat ini. (Karakter <> digunakan di sini untuk kejelasan visual dan tidak dapat menjadi bagian dari string jalur yang valid.)

Sekarang kita melihat bahwa itu adalah 1 + 2 + 256 + 1 atau [drive] [: \] [path] [null] = 260. Orang dapat berasumsi bahwa 256 adalah panjang string tetap yang masuk akal dari hari-hari DOS. Dan kembali ke API DOS, kami menyadari bahwa sistem melacak jalur saat ini per drive, dan kami memiliki 26 (32 dengan simbol) drive maksimum (dan direktori saat ini).

INT 0x21 AH = 0x47 mengatakan "Fungsi ini mengembalikan deskripsi jalur tanpa huruf drive dan backslash awal." Jadi kita melihat bahwa sistem menyimpan CWD sebagai pasangan (drive, path) dan Anda meminta path dengan menentukan drive (1 = A, 2 = B, ...), jika Anda menentukan 0 maka ia mengasumsikan path untuk drive dikembalikan oleh INT 0x21 AH = 0x15 AL = 0x19. Jadi sekarang kita tahu mengapa itu 260 dan bukan 256, karena 4 byte itu tidak disimpan dalam string path.

Mengapa string jalur 256 byte, karena 640K cukup RAM.

valli
sumber
21
Windows API membatasi panjangnya, bahkan di OS terbaru. Microsoft takut untuk menghancurkan ratusan juta sistem operasi yang digunakan saat ini jika ini berubah karena mereka tidak memiliki genius yang bekerja untuk mereka lagi yang memahami API luar dalam, seperti yang mereka lakukan pada 1980-an dan 1990-an. Risikonya tidak layak diubah. serverfault.com/questions/163419/…
MacGyver
77
@ MacGyver Maaf, tapi itu omong kosong. Microsoft tidak ingin memecah jutaan aplikasi yang ditulis dengan buruk di luar sana yang mengasumsikan hal-hal tentang sistem yang tidak pernah dijamin. Sayangnya, semuanya adalah cara yang sama begitu lama sehingga pengembang datang untuk mengandalkan mereka, jadi mengubahnya sekarang akan merusak aplikasi pihak ke-3 dan MS akan disalahkan.
Dasar
25
btw tidak ada bukti bahwa Gates pernah mengatakan "Ram 640K sudah cukup untuk semua orang" computerworld.com/article/2534312
Patrick Favre
11
@Basic Batas 260 karakter dijamin oleh Windows. Konstanta dideklarasikan sebagai konstanta , struktur dideklarasikan dalam file header Windows yang hanya memiliki ruang untuk 260 karakter. Tidak ada cara untuk mengubahnya.
Ian Boyd
35
@ Dasar Konstanta tidak berubah setelah dikompilasi ke dalam aplikasi saya. Saya menjalankan aplikasi yang terakhir dibangun pada tahun 1994, dan masih berjalan hari ini di Windows 10. Microsoft menjanjikan ukuran biner tertentu dari blok memori, dan programmer mengikuti aturan itu. Jika Microsoft mengubah konstanta, maka setiap aplikasi yang ada, yang mengikuti API pemrograman dengan benar, akan rusak . Anda tidak dapat merusak kompatibilitas biner.
Ian Boyd
150

Ini tidak sepenuhnya benar karena sistem file NTFS mendukung jalur hingga 32 ribu karakter. Anda dapat menggunakan api win32 dan " \\?\" awalan jalur untuk menggunakan lebih dari 260 karakter.

Penjelasan terperinci tentang jalur panjang dari blog tim .Net BCL .
Kutipan kecil menyoroti masalah dengan jalur panjang

Kekhawatiran lain adalah perilaku tidak konsisten yang akan dihasilkan dengan memaparkan dukungan jalur panjang. Jalur panjang dengan \\?\awalan dapat digunakan di sebagian besar API Windows terkait file, tetapi tidak semua API Windows. Misalnya, LoadLibrary, yang memetakan modul ke alamat proses panggilan, gagal jika nama file lebih panjang dari MAX_PATH. Jadi ini berarti MoveFile akan membiarkan Anda memindahkan DLL ke lokasi sehingga jalurnya lebih dari 260 karakter, tetapi ketika Anda mencoba memuat DLL, itu akan gagal. Ada contoh serupa di seluruh API Windows; beberapa solusi ada, tetapi mereka berdasarkan kasus per kasus.

softveda
sumber
4
Cukup adil, tetapi itu berarti Anda harus menggunakan P / Invoke di banyak tempat dan ini, menurut saya, mengurangi portabilitas kode .Net Anda. Bagaimana jika saya ingin menjaga kompatibilitas Mono?
Jeffrey Cameron
1
Maksud saya adalah Anda dapat menggunakan jalur panjang jika Anda benar-benar menginginkannya. Tetapi saya setuju bahwa itu menyakitkan dan secara pribadi saya akan menghindari ini juga.
softveda
5
Ini harus menjadi jawaban yang dipilih. Sebenarnya menjawab pertanyaan yang diajukan oleh pengguna MENGAPA batas ini ada DAN menyediakan solusi.
Suara positif
2
Kedengarannya bagi saya bahwa Microsoft perlu memperbaiki API mereka, dan saya kira ini bukan prioritas. Saya terkejut bahwa batas ini masih ada di Windows 8.
Mas
3
@Mas "Perbaikan" yang Anda inginkan dilakukan semua kembali ke Windows XP. Memanggil versi unicode API mereka akan memungkinkan Anda untuk mengakses "jalur yang diperluas". Saya percaya penjelajah secara otomatis menangani ini. Berikut adalah salah satu fungsi yang mendukungnya - msdn.microsoft.com/en-us/library/windows/desktop/… .
Natalie Adams
108

Pertanyaannya adalah mengapa batasan itu masih ada. Tentunya Windows modern dapat meningkatkan sisi MAX_PATHuntuk memungkinkan jalur yang lebih panjang. Mengapa batasan belum dihapus?

  • Alasan itu tidak bisa dihapus adalah bahwa Windows berjanji tidak akan pernah berubah.

Melalui kontrak API, Windows telah menjamin semua aplikasi bahwa API file standar tidak akan pernah mengembalikan jalur yang lebih panjang daripada 260karakter.

Pertimbangkan kode yang benar berikut ini :

WIN32_FIND_DATA findData;

FindFirstFile("C:\Contoso\*", ref findData);

Windows menjamin program saya bahwa itu akan mengisi WIN32_FIND_DATAstruktur saya :

WIN32_FIND_DATA {
   DWORD    dwFileAttributes;
   FILETIME ftCreationTime;
   FILETIME ftLastAccessTime;
   FILETIME ftLastWriteTime;
   //...
   TCHAR    cFileName[MAX_PATH];
   //..
}

Aplikasi saya tidak menyatakan nilai konstanta MAX_PATH, API Windows melakukannya. Aplikasi saya menggunakan nilai yang ditentukan itu.

Struktur saya didefinisikan dengan benar, dan hanya mengalokasikan 592total byte. Itu berarti bahwa saya hanya dapat menerima nama file yang kurang dari 260karakter. Windows berjanji kepada saya bahwa jika saya menulis aplikasi saya dengan benar, aplikasi saya akan terus berfungsi di masa depan.

Jika Windows mengizinkan nama file lebih panjang dari 260karakter maka aplikasi saya yang ada (yang menggunakan API yang benar dengan benar) akan gagal.

Bagi siapa pun yang meminta Microsoft untuk mengubah MAX_PATHkonstanta, pertama-tama mereka perlu memastikan bahwa tidak ada aplikasi yang gagal. Misalnya, saya masih memiliki dan menggunakan aplikasi Windows yang ditulis untuk dijalankan pada Windows 3.11. Ini masih berjalan pada Windows 10. 64-bit. Itulah yang membuat kompatibilitas Anda mundur.

Microsoft memang menciptakan cara untuk menggunakan nama path lengkap 32.768; tetapi mereka harus membuat kontrak API baru untuk melakukannya. Untuk satu, Anda harus menggunakan Shell API untuk menghitung file (karena tidak semua file ada di hard drive atau jaringan berbagi).

Tetapi mereka juga harus tidak merusak aplikasi pengguna yang ada. Sebagian besar aplikasi tidak menggunakan api shell untuk kerja file. Semua orang hanya menelepon FindFirstFile/ FindNextFiledan menyebutnya sehari.

Ian Boyd
sumber
4
@JosiahKeller Jika ya, itu akan memutus kontrak yang awalnya ditentukan untuk metode itu, dan melakukan itu bisa menimpa memori yang tidak diinginkan, dan membuka celah keamanan. Satu-satunya cara untuk memperbaikinya adalah dengan menawarkan API baru yang ditingkatkan (seperti varian Unicode aware), dan berharap semua orang mengkompilasi ulang / merilis kembali semua aplikasi mereka menggunakan API yang lebih baru.
Rowland Shaw
2
@Ryios Saya tidak berpikir aplikasi Windows saya yang ada akan berjalan di Linux.
Ian Boyd
9
Kompatibilitas mundur bagus. Tapi saya pikir menghindari masalah seperti itu (seringkali sangat tidak menyenangkan) hari ini lebih penting daripada mendukung aplikasi Windows 3.1. Berapa banyak orang yang mengalami masalah dengan jalur panjang? Dan berapa banyak orang yang masih menggunakan aplikasi Windows 3.1? Mereka bahkan membatalkan dukungan untuk Windows XP. Jadi mengapa mereka tidak membuat pengumuman, bahwa dari Windows [x] dan kemudian aplikasi yang menganggap tidak akan ada jalur lebih dari 260 karakter, tidak akan berfungsi seperti yang diharapkan ketika mereka menambahkan jalur yang terlalu panjang? Batas kecepatan kami juga tidak menganggap kereta.
JuSchu
2
@JuSchu Ini bukan hanya aplikasi Windows 3.1. Aplikasi yang ditulis hari ini menggunakan API yang benar tidak akan berfungsi.
Ian Boyd
62

Dari Windows 10. Anda dapat menghapus batasan dengan memodifikasi kunci registri.

Tip Mulai pada Windows 10, versi 1607, batasan MAX_PATH telah dihapus dari fungsi file dan direktori Win32 yang umum. Namun, Anda harus ikut serta ke perilaku baru.

Kunci registri memungkinkan Anda untuk mengaktifkan atau menonaktifkan perilaku jalur panjang baru. Untuk mengaktifkan perilaku jalur panjang atur kunci registri di HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled(Ketik:) REG_DWORD. Nilai kunci akan di-cache oleh sistem (per proses) setelah panggilan pertama ke file Win32 yang terpengaruh atau fungsi direktori (daftar berikut). Kunci registri tidak akan dimuat ulang selama masa proses. Agar semua aplikasi pada sistem mengenali nilai kunci, reboot mungkin diperlukan karena beberapa proses mungkin telah dimulai sebelum kunci ditetapkan. Kunci registri juga dapat dikontrol melalui Kebijakan Grup di Computer Configuration > Administrative Templates > System > Filesystem > Enable NTFS long paths. Anda juga dapat mengaktifkan perilaku jalur panjang baru per aplikasi melalui manifes:

<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>
Root Loop
sumber
15
Sedih bahkan di versi terbaru Win10, File Explorer itu sendiri masih memiliki masalah berurusan dengan nama jalur panjang. Bahkan "Salin sebagai Path" di menu konteks tidak berfungsi seperti yang diharapkan; itu hanya menyalin 260 karakter pertama. Anda tidak dapat membuat folder, menyalin / memindahkan / membuka file ... Buat saya bertanya-tanya apa gunanya perubahan ini.
raymai97
Perhatikan bahwa klaim bahwa pengaturan sistem independen dari pengaturan manifes salah. Keduanya dibutuhkan. Kebijakan tersebut harus diaktifkan pada tingkat sistem dan manifes harus menyatakan bahwa aplikasi tersebut sadar jalur panjang.
Eryk Sun
Saya membaca bahwa membuat perubahan ini dapat menyebabkan masalah kompatibilitas dengan aplikasi 32-bit yang lebih lama, tetapi apakah jenis masalah dengan kompatibilitas ini umum? Saya ingin melakukan perubahan sendiri. lifehacker.com/...
KDP
32

Anda dapat memasang folder sebagai drive. Dari baris perintah, jika Anda memiliki jalur, C:\path\to\long\folderAnda dapat memetakannya ke huruf drive X:menggunakan:

subst x: \path\to\long\folder
Jonchang
sumber
saya menerima "Parameter tidak valid j:" saat mencoba perintah ini
barrypicker
Ini perlu dijalankan dari prompt perintah Administrator (tinggi).
Mrchief
Ini akan gagal dengan garis miring ke depan, perlu garis miring terbalik.
cchamberlain
1
Saya tidak yakin apakah ini hanya berlaku untuk windows 10, namun saya baru saja menemukan bahwa ketika mencoba menjalankan perintah ini, jika saya menjalankan sebagai administrator seperti yang disarankan di atas drive tampaknya tidak tersedia. Ini karena perilaku yang kelihatannya mirip dengan memetakan drive jaringan dan spesifik sesi dll, jadi ketika saya berlari sebagai administrator dan menggunakan perintah ini, sesi itu bisa menggunakan x: TL; DR Jika Anda tidak dapat melihat drive mencoba menjalankan perintah tanpa berada dalam mode administrator.
Jaddie
substadalah sesi / akun lokal - lihat superuser.com/questions/29072/… untuk cara menjadikannya 'sistem luas'
user2864740
18

Salah satu cara untuk mengatasi batas jalur adalah mempersingkat entri jalur dengan tautan simbolik.

Sebagai contoh:

  1. buat C:\pdirektori untuk menyimpan tautan pendek ke jalur panjang
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. tambahkan C:\p\fooke jalur Anda alih-alih jalur panjang
JDiMatteo
sumber
3
Tidak harus membuat direktori terlebih dahulu, jadi langkah 1 tidak perlu.
ohaal
2
Trik ini tidak selalu berhasil karena banyak aplikasi mencoba menyelesaikan tautan
nponeccop
The /jpilihan menciptakan mountpoint persimpangan untuk perangkat volume yang lokal atau jalan pada volume lokal (seperti Unix bind mount). Itu tidak membuat tautan simbolis. Ini perbedaan penting karena titik mount persimpangan selalu dievaluasi pada server dan harus menargetkan perangkat lokal, sementara tautan simbolik dievaluasi pada klien dan dapat menargetkan jalur jarak jauh (jika diizinkan oleh kebijakan). Seperti drive subt.exe (yaitu DefineDosDeviceW), target persimpangan biasanya terbatas pada sekitar 4K karakter. Ini sebenarnya 8K karakter, terbagi rata antara jalur pengganti dan jalur tampilan.
Eryk Sun
12

Anda dapat mengaktifkan nama jalur panjang menggunakan PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Type DWord -Value 1 

Versi lain adalah dengan menggunakan Group Policy di Computer Configuration/ Administrative Templates/ System/ Filesystem:

Editor Kebijakan Grup

MovGP0
sumber
2
Setiap aplikasi masih harus menyatakan bahwa itu adalah jalur panjang yang disadari. Microsoft telah melakukan pekerjaan yang buruk dalam mengkomunikasikan hal ini dengan membuatnya tampak seperti manifes aplikasi hanyalah cara lain untuk mengaktifkan fitur ini, daripada dengan jelas menjelaskan bahwa itu adalah kontrak antara OS (kebijakan tingkat sistem) dan aplikasi yang harus disetujui keduanya.
Eryk Sun
8

Seperti mengapa ini masih ada - MS tidak menganggapnya sebagai prioritas, dan nilai kompatibilitas mundur lebih dari memajukan OS mereka (setidaknya dalam contoh ini).

Solusi yang saya gunakan adalah menggunakan "nama pendek" untuk direktori di jalur, alih-alih versi standar mereka yang dapat dibaca oleh manusia. Jadi misalnya untuk C:\Program Files\saya akan menggunakan C:\PROGRA~1\ Anda dapat menemukan setara menggunakan nama pendek dir /x.

Conrad
sumber
1
Nama jalur pendek dapat dinonaktifkan di registri (atau apakah itu sistem file itu sendiri?), Jadi ini sebenarnya bukan solusi yang dapat diandalkan.
rubenvb
3
@rubenvb Saya yakin sebagian besar jika tidak semua fitur Windows dapat dinonaktifkan di registri jadi ¯ \ _ (ツ) _ / ¯
Conrad
Membuat nama pendek dapat dinonaktifkan untuk NTFS (dan seharusnya karena tidak efisien dalam banyak kasus), baik untuk keseluruhan sistem atau per volume, sehingga ini merupakan pendekatan yang tidak dapat diandalkan bahkan untuk jalur pada drive sistem, yang harus NTFS. Dimungkinkan untuk secara manual mengatur nama pendek pada file dan direktori di NTFS, tetapi ini tidak mencakup sistem file yang lebih baru yang sama sekali tidak mendukung nama pendek, seperti exFAT dan ReFS. Nama pendek harus dianggap sebagai fitur usang yang dipertahankan untuk kompatibilitas dalam kasus-kasus terbatas, seperti ANSI / OEM API lama menggunakan kode byte tunggal dan ganda.
Eryk Sun
@eryksun Silakan lihat komentar saya sebelumnya tentang menonaktifkan nama jalur pendek. :) Hanya karena Anda pikir itu harus dianggap usang, bukan berarti itu sebenarnya. MS tidak memiliki rencana untuk menghentikan fitur ini. (Juga, mengapa Anda menginstal perangkat lunak Windows pada partisi exFAT / ReFS?)
Conrad
Saya masih mengatakan untuk hanya menggunakan jalur perangkat yang tidak dinormalisasi (yaitu awalan "\\? \"), Karena selalu tersedia dan jelas. Misalnya, terjemahkan PATHdan berikan kepada SearchPathW. Ini juga efisien, karena perpustakaan runtime membuat jalur perangkat "\\? \" Untuk NT. Mengenai sistem file yang lebih baru, kita mungkin tidak akan melihat perangkat lunak diinstal pada volume exFAT, selain aplikasi portabel, karena tidak memiliki keamanan, tapi saya tidak akan mengesampingkan ReFS. Pengguna memasang program di lokasi non-standar untuk alasan kenyamanan, ruang, atau kinerja.
Eryk Sun
7

Mengenai cara mengatasi batasan ukuran lintasan pada Windows - menggunakan 7zip untuk mengemas (dan membuka paket) file sensitif lintasan Anda tampak seperti solusi yang layak. Saya telah menggunakannya untuk mengangkut beberapa instalasi IDE (jalur plugin Eclipse, ya!) Dan tumpukan dokumentasi yang di-autogenerasi dan sejauh ini tidak memiliki masalah.

Tidak begitu yakin bagaimana cara menghindari batas 260 char yang ditetapkan oleh Windows (dari PoV teknis), tapi hei, itu berhasil!

Lebih detail di halaman SourceForge mereka di sini :

"NTFS sebenarnya dapat mendukung nama path hingga 32.000 karakter."

7-zip juga mendukung nama panjang tersebut.

Tapi itu dinonaktifkan dalam kode SFX. Beberapa pengguna tidak menyukai jalur yang panjang, karena mereka tidak mengerti cara bekerja dengannya. Itu sebabnya saya menonaktifkannya dalam kode SFX.

dan lepaskan catatan :

9.32 alpha 2013-12-01

  • Peningkatan dukungan untuk nama path file lebih dari 260 karakter.

4.44 beta 2007-01-20

  • 7-Zip sekarang mendukung nama path file lebih dari 260 karakter.

CATATAN PENTING: Agar ini berfungsi dengan baik, Anda harus menentukan jalur tujuan dalam dialog "Ekstrak" 7zip secara langsung, daripada menyeret & menjatuhkan file ke folder yang dimaksud. Jika tidak, folder "Temp" akan digunakan sebagai cache sementara dan Anda akan terpental ke batasan karakter yang sama setelah Windows Explorer mulai memindahkan file ke "tempat peristirahatan terakhir" mereka. Lihat balasan untuk pertanyaan ini untuk informasi lebih lanjut.

Priidu Neemre
sumber
3
Saya salah, 7zip dan WinRAR lakukan ekstrak semua folder dan file. Hanya saja properti folder di Windows hanya melaporkan jumlah folder dan file yang tidak melanggar batasan. Seolah-olah Windows Explorer tidak menggali lebih dalam lagi untuk menemukan folder ketika jalur maks tercapai.
Twisted Whisper
Dimungkinkan untuk menghapus jalur panjang di 7-zip dengan shift-del.
Laurie Stearn
Jawaban singkat - gunakan 7zip untuk membuka zip file .zip .... bekerja untuk saya di Windows 7
andrewcockerham
2

Cara lain untuk mengatasinya adalah dengan menggunakan Cygwin, tergantung pada apa yang ingin Anda lakukan dengan file (yaitu jika perintah Cygwin sesuai dengan kebutuhan Anda)

Misalnya memungkinkan untuk menyalin, memindahkan, atau mengganti nama file yang bahkan Windows Explorer tidak bisa. Atau tentu saja berurusan dengan kontennya seperti md5sum, grep, gzip, dll.

Juga untuk program yang Anda koding, Anda dapat menautkannya ke Cygwin DLL dan itu akan memungkinkan mereka untuk menggunakan jalur panjang (saya belum menguji ini)

eliblanco87
sumber