Cara terbaik untuk menyelesaikan pengecualian jalur file terlalu panjang

109

Saya membuat aplikasi yang mengunduh semua pustaka dokumen di Situs SP, tetapi pada satu titik itu memberi saya kesalahan ini (saya mencoba melihat google tetapi tidak dapat menemukan apa pun, sekarang jika ada yang tahu trik untuk menyelesaikan masalah ini, silakan tanggapi jika tidak terima kasih untuk melihatnya)

System.IO.PathTooLongException: Path yang ditentukan, nama file, atau keduanya terlalu panjang. Nama file yang memenuhi syarat harus kurang dari 260 karakter, dan nama direktori harus kurang dari 248 karakter. di System.IO.Path.NormalizePathFast (Jalur string, Boolean fullCheck) di System.IO.Path.GetFullPathInternal (jalur string) di System.IO.FileStream.Init (Jalur string, mode FileMode, akses FileAccess, hak Int32, Boolean useRights , Berbagi FileShare, Int32 bufferSize, opsi FileOptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) di System.IO.FileStream..ctor (jalur String, mode FileMode, akses FileAccess, berbagi FileShare, Int32 bufferSize, opsi FileOptions) di Sistem. IO.File.Create (Jalur string)

itu mencapai batas untuk string, Kode diberikan di bawah ini,

#region Downloading Schemes

    private void btnDownload_Click(object sender, EventArgs e)
    {
        TreeNode currentNode = tvWebs.SelectedNode;
        SPObjectData objectData = (SPObjectData)currentNode.Tag;
        try
        {
            CreateLoggingFile();
            using (SPWeb TopLevelWeb = objectData.Web)
            {
                if(TopLevelWeb != null)
                    dwnEachWeb(TopLevelWeb, TopLevelWeb.Title, tbDirectory.Text);
            }
        }
        catch (Exception ex)
        {
            Trace.WriteLine(string.Format("Exception caught when tried to pass TopLevelWeb:{1}, Title = {2}, object data to (dwnEachWeb_method), Exception: {0}", ex.ToString(), objectData.Web, objectData.Title));
        }
        finally
        {
            CloseLoggingFile();
        }
    }

    private void dwnEachWeb(SPWeb TopLevelWeb, string FolderName, string CurrentDirectory)
    {
        if (TopLevelWeb != null)
        {
            if (TopLevelWeb.Webs != null)
            {
                CurrentDirectory = CurrentDirectory + "\\" + TopLevelWeb.Title;
                CreateFolder(CurrentDirectory);
                foreach (SPWeb ChildWeb in TopLevelWeb.Webs)
                {

                    dwnEachWeb(ChildWeb, ChildWeb.Title, CurrentDirectory);
                    ChildWeb.Dispose();
                }
                dwnEachList(TopLevelWeb, CurrentDirectory);
                //dwnEachList(TopLevelWeb, FolderName, CurrentDirectory);
            }
        }
    }

    private void dwnEachList(SPWeb oWeb, string CurrentDirectory)
    {
        foreach (SPList oList in oWeb.Lists)
        {
            if (oList is SPDocumentLibrary && !oList.Hidden)
            {
                dwnEachFile(oList.RootFolder, CurrentDirectory);
            }
        }
    }

    private void dwnEachFile(SPFolder oFolder, string CurrentDirectory)
    {
        if (oFolder.Files.Count != 0)
        {
            CurrentDirectory = CurrentDirectory + "\\" + oFolder.Name;
            CreateFolder(CurrentDirectory);
            foreach (SPFile ofile in oFolder.Files)
            {
                if (CreateDirectoryStructure(CurrentDirectory, ofile.Url))
                {
                    var filepath = System.IO.Path.Combine(CurrentDirectory, ofile.Url);
                    byte[] binFile = ofile.OpenBinary();
                    System.IO.FileStream fstream = System.IO.File.Create(filepath);
                    fstream.Write(binFile, 0, binFile.Length);
                    fstream.Close();
                }
            }
        }
    }

    //creating directory where files will be download        
    private bool CreateDirectoryStructure(string baseFolder, string filepath)
    {
        if (!Directory.Exists(baseFolder)) return false;

        var paths = filepath.Split('/');

        for (var i = 0; i < paths.Length - 1; i++)
        {
            baseFolder = System.IO.Path.Combine(baseFolder, paths[i]);
            Directory.CreateDirectory(baseFolder);
        }
        return true;
    }

    //creating folders
    private bool CreateFolder(string CurrentDirectory)
    {
        if (!Directory.Exists(CurrentDirectory))
        {
            Directory.CreateDirectory(CurrentDirectory);
        }
        return true;
    }

    //shorting string

    #endregion
Muhammad Raja
sumber
1
Ubah jalur UNC (atau apa pun) menjadi format 8.3. [Ubah ke format 8.3 menggunakan CMD] [1] [1]: stackoverflow.com/questions/10227144/…
AutomationNation
Kemungkinan duplikat. Di sini saya menemukan solusi stackoverflow.com/a/44211420/5312148
Francesco

Jawaban:

58

Karena penyebab kesalahan sudah jelas, berikut beberapa informasi yang akan membantu Anda menyelesaikan masalah:

Lihat artikel MS ini tentang Penamaan File, Paths, dan Namespaces

Berikut kutipan dari tautan:

Batasan Panjang Jalur Maksimum Di Windows API (dengan beberapa pengecualian yang dibahas dalam paragraf berikut), panjang maksimum jalur adalah MAX_PATH, yang didefinisikan sebagai 260 karakter. Lintasan lokal disusun dalam urutan berikut: huruf kandar, titik dua, garis miring terbalik, komponen nama yang dipisahkan oleh garis miring terbalik, dan karakter null penghentian. 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 halaman kode sistem saat ini. (Karakter <> digunakan di sini untuk kejelasan visual dan tidak dapat menjadi bagian dari string jalur yang valid.)

Dan beberapa solusi (diambil dari komentar):

Ada cara untuk mengatasi berbagai masalah tersebut. Ide dasar dari solusi yang tercantum di bawah ini selalu sama: Kurangi panjang jalur agar memiliki path-length + name-length < MAX_PATH. Kamu boleh:

  • Bagikan subfolder
  • Gunakan baris perintah untuk menetapkan huruf drive melalui SUBST
  • Gunakan AddConnection di bawah VB untuk menetapkan huruf drive ke jalur
James Hill
sumber
7
@TimeToThine, apakah Anda membaca artikel yang saya posting? Apakah kamu membaca komentarnya? Saya bisa saja salah, tetapi saya rasa Anda tidak akan mendapatkan bantuan lagi dari komunitas SO, selain yang telah saya berikan.
James Hill
2
Ya, saya sudah membacanya sebelum memposting pertanyaan saya di sini, saya bahkan mencoba "\\? \" Tetapi untuk beberapa alasan ini tidak berfungsi dalam konteks ini. Saya menemukan blog ini, sedang menggunakannya tetapi untuk beberapa alasan tidak berfungsi dengan baik, " codinghorror.com/blog/2006/08/shortening-long-file-paths.html " Saya masih mencari sesuatu yang membuat direktori tetap tersimpan dan saya bisa mengambilnya dari sana, atau sesuatu seperti itu, misalnya menggunakan label tersembunyi untuk menyimpan direktori saat ini, bukan string, tetapi tidak yakin apakah itu akan berhasil.
Muhammad Raja
24
Itu jelas tapi tidak masuk akal. Mengapa ada batasan ukuran jalur ??? sekarang 2017.
Jaider
2
Jika saya mengubah direktori saat ini ke direktori folder menggunakan Directory.SetCurrentDirectory () apakah itu akan menghindari pembatasan ini. Atau apakah masalahnya masih ada.
Adam Lindsay
3
Artikel tersebut tampaknya telah diperbarui: Starting in Windows 10, version 1607, MAX_PATH limitations have been removed from common Win32 file and directory functions. Namun Anda harus ikut serta, dan menyetel kunci registri untuk mengaktifkannya.
Tom Deblauwe
28

Solusi yang berhasil bagi saya adalah mengedit kunci registri untuk mengaktifkan perilaku jalur panjang, menyetel nilainya ke 1. Ini adalah fitur keikutsertaan baru untuk Windows 10

HKLM\SYSTEM\CurrentControlSet\Control\FileSystem LongPathsEnabled (Type: REG_DWORD)

Saya mendapat solusi ini dari bagian bernama artikel yang diposting @ james-hill.

https://docs.microsoft.com/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation

goonerify
sumber
2
Saya menetapkan ini ke 1 dan masih mendapatkan kesalahan, tidak tahu mengapa pada saat ini.
Mr Angry
Artikel tersebut menyebutkan dua persyaratan. Pertama kunci registri, dan kedua aplikasi xml: <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </windowsSettings> </application>Bagi saya di Visual Studio 2019, persyaratan kedua ini tidak diperlukan setelah memulai ulang Visual Studio.
Tom Anderson
Maaf mungkin ini pertanyaan bodoh tapi Apa itu "aplikasi xml"? Apakah web.config atau yang lainnya? Saya memiliki masalah ini pada proyek asp.net Halaman Web
Ondra Starenko
Seperti yang dikatakan di atas, ini berfungsi dengan baik di Visual Studio 2019 (setelah restart) tanpa mengubah aplikasi xml. Terima kasih atas solusinya.
Zoman
@TomAnderson: Saya menggunakan VS2017. Di mana iI dapat menemukan application.xml ini? karena setelah melakukan langkah 1 tidak menyelesaikan masalah saya.
Sharad
3

Anda dapat membuat tautan simbolis dengan direktori yang lebih pendek. Pertama buka baris perintah misalnya dengan Shift + RightClickdi folder yang Anda inginkan dengan jalur yang lebih pendek (Anda mungkin harus menjalankannya sebagai administrator).

Kemudian ketik dengan jalur relatif atau absolut:

mklink ShortPath\To\YourLinkedSolution C:\Path\To\Your\Solution /D

Dan kemudian mulai Solusi dari jalur yang lebih pendek. Keuntungannya di sini adalah: Anda tidak perlu memindahkan apapun.

Markus Weber
sumber
Ini tidak berfungsi di VS2015. Tampaknya VS sedang mengatur panjang jalur. Lihat jawaban N-Ate untuk solusi VS2015.
T-makan
1
Apa yang dapat Anda lakukan adalah memetakan folder solusi ke driver menggunakan perintah "subst". Itu berfungsi untuk VS2017.
Filipe Calasans
2

Di Windows 8.1, menggunakan. NET 3.5, saya mengalami masalah serupa.
Meskipun nama file saya hanya 239 karakter ketika saya pergi untuk membuat instance objek FileInfo hanya dengan nama file (tanpa path) terjadi pengecualian tipe System. IO.PathTooLongException

2014-01-22 11:10:35 DEBUG LogicalDOCOutlookAddIn.LogicalDOCAddIn - fileName.Length: 239 
2014-01-22 11:10:35 ERROR LogicalDOCOutlookAddIn.LogicalDOCAddIn - Exception in ImportEmail System.IO.PathTooLongException: Percorso e/o nome di file specificato troppo lungo. Il nome di file completo deve contenere meno di 260 caratteri, mentre il nome di directory deve contenere meno di 248 caratteri.
   in System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)
   in System.IO.FileInfo..ctor(String fileName)
   in LogicalDOCOutlookAddIn.LogicalDOCAddIn.GetTempFilePath(String fileName) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 692
   in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmail(_MailItem mailItem, OutlookConfigXML configXML, Int64 targetFolderID, String SID) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 857
   in LogicalDOCOutlookAddIn.LogicalDOCAddIn.ImportEmails(Explorers explorers, OutlookConfigXML configXML, Int64 targetFolderID, Boolean suppressResultMB) in C:\Users\alle\Documents\Visual Studio 2010\Projects\MyAddin1Outlook20072010\MyAddin1Outlook20072010\LogicalDOCAddIn.cs:riga 99

Saya menyelesaikan masalah pemangkasan nama file menjadi 204 karakter (termasuk ekstensi).

Marcel Piquet
sumber
Info tambahan untuk siapa saja yang membaca ini - Nama file dibatasi hingga 247 karakter sedangkan jalur lengkap dibatasi hingga 259. Jadi jika nama file Anda 239, itu hanya menyisakan 20 karakter untuk sisa jalur (misalnya "c: \ temp") . Jika Anda memangkas nama file, Anda perlu memastikan jalur LENGKAP adalah 259 karakter atau kurang.
Losbear
1

Jika Anda mengalami masalah dengan file bin Anda karena jalur yang panjang, Dalam Visual Studio 2015 Anda dapat pergi ke halaman properti proyek yang melanggar dan mengubah Direktori Output relatif ke yang lebih pendek.

Misalnya bin \ debug \ menjadi C: \ _ bins \ MyProject \

N-makan
sumber
1
Setelah membuka kembali properti ketika build saya gagal, saya melihat jalur baru "c: \ vs \ bin \ Release" diganti sebagai ".. \ .. \ .. \ .. \ .. \ .. \ .. \. . \ vs \ bin \ Rilis \ " . Saya tidak yakin apakah ".. \" difaktorkan ke dalam jumlah karakter.
samis
2
Jalur yang dievaluasi sebagai jalur yang terlalu panjang adalah jalur absolut.
N-makan
1

Apa yang berhasil untuk saya adalah memindahkan proyek saya seperti yang ada di desktop (C: \ Users \ lachezar.l \ Desktop \ MyFolder) ke (C: \ 0 \ MyFolder) yang seperti yang Anda lihat menggunakan jalur yang lebih pendek dan menguranginya menyelesaikan masalah.

Lachezar Lalov
sumber
1

Dari pengalaman saya, tidak akan merekomendasikan jawaban saya di bawah ini untuk aplikasi Web yang dihadapi publik.

Jika Anda membutuhkannya untuk alat inhouse Anda atau untuk Pengujian, saya akan merekomendasikan untuk membagikannya di mesin Anda sendiri.

-Right click on the root path you need to access
-Choose Properties
-Click on Share button and add your chosen users who can access it

Ini kemudian akan membuat direktori bersama seperti \\ {PCName} \ {YourSharedRootDirectory} Ini pasti jauh lebih sedikit dari jalur lengkap Anda. Saya harap, bagi saya, saya dapat mengurangi menjadi 30 karakter dari sekitar 290 karakter. :)

Riyaz Hameed
sumber
0

Belum lagi sejauh ini dan pembaruan, ada perpustakaan yang didirikan dengan sangat baik untuk menangani jalur yang terlalu panjang. AlphaFS adalah pustaka .NET yang menyediakan fungsionalitas sistem file Win32 yang lebih lengkap ke platform .NET daripada kelas System.IO standar. Kekurangan yang paling menonjol dari .NET System.IO standar adalah kurangnya dukungan fitur NTFS tingkat lanjut, terutama dukungan jalur panjang yang diperpanjang (misalnya jalur file / direktori yang lebih panjang dari 260 karakter).

Markus
sumber
0

Jawaban terbaik yang bisa saya temukan, ada di salah satu komentar di sini. Menambahkannya ke jawaban sehingga seseorang tidak akan melewatkan komentar dan harus mencobanya. Ini memperbaiki masalah saya.

Kita perlu memetakan folder solusi ke drive menggunakan perintah "subst" di command prompt- misalnya, subst z:

Dan kemudian buka solusi dari drive ini (z dalam kasus ini). Ini akan mempersingkat jalur sebanyak mungkin dan dapat menyelesaikan masalah nama file yang panjang.

Jatin Nath Prusty
sumber
0

ini mungkin juga solusi. Terkadang juga terjadi ketika Anda menyimpan proyek Pengembangan Anda terlalu dalam, berarti mungkin direktori proyek mungkin memiliki terlalu banyak direktori jadi tolong jangan membuat terlalu banyak direktori, simpan dalam folder sederhana di dalam drive. Sebagai Contoh- Saya juga mendapatkan kesalahan ini ketika proyek saya disimpan seperti ini-

D: \ Sharad \ LatestWorkings \ GenericSurveyApplication020120 \ GenericSurveyApplication \ GenericSurveyApplication

lalu saya cukup Menempelkan proyek saya di dalam

D: \ Sharad \ LatestWorkings \ GenericSurveyApplication

Dan Masalah terpecahkan.

pengguna3820036
sumber