C# 一步步解決DotNetZip因超長路徑(MAX_PATH)報(bào)錯(cuò)的問題
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
一、前言超長路徑(MAX_PATH)的問題,在很多地方都可能遇到,常見的解決辦法無非三種:添加前綴\\?\、app.config添加配置、修改注冊表等。 而對于其它第三方的DLL,我們?nèi)绾稳耐獠拷鉀Q呢?答案是:反射。 本篇文章,我們就以DotNetZip為例,一步步來解決超長路徑的問題。 **相信看完的你,一定會有所收獲! 二、一步步定位問題首先,我們看下使用DotNetZip的ZipEntry.AddDictionary()方法添加一個(gè)目錄后,相關(guān)屬性的變化。 我們可以看到,在添加前,ZipFile.Entries是空的。 在添加后,變化如下: 會遇到超長路徑(MAX_PATH)報(bào)錯(cuò),肯定會有一個(gè)完整的路徑,當(dāng)然存在臨時(shí)拼接的情況,但是我們先找一找。 最后,我們在“非公開成員”中找到一個(gè)屬性:LocalFileName,其值正是完整的文件路徑,如下圖所示: 為了方便觀察,我們將LocalFileName屬性置頂顯示: 之后我們就可以看到,默認(rèn)顯示的都是LocalFileName了: 現(xiàn)在我們找到這個(gè)關(guān)鍵的LocalFileName,雖然還不能百分百確定和這有關(guān),但是可以以此為準(zhǔn)進(jìn)行后面的排查和驗(yàn)證了。 三、反編譯梳理邏輯像DotNetZip,是開源的,我們可以直接找到源碼來查看,對于非開源的,我們就只能反編譯了。 這里常用的工具是dnSpy,我們使用dnSpy打開DotNetZip,然后定位到ZipEntry,再找到LocalFileName屬性: 可以看到只有g(shù)et,沒有set,這樣的話,如果直接反射操作此屬性,則需要額外的添加set訪問器,非常麻煩,此時(shí)不作考慮。 我們再看,LocalFileName其實(shí)是返回的變量:_LocalFileName,我們再找下此變量: 這樣的話就簡單了,我們反射直接操作此變量: 我們在處理時(shí),先進(jìn)行判斷是否超長,再反射處理,因?yàn)榉瓷涫呛芎馁Y源的。 至于擴(kuò)展方法,定義如下: 說一下這里面為什么要以248作為判斷條件,是因?yàn)?60是文件路徑限制,而對于目錄則是以248為限制,所以我們以最小的為主進(jìn)行判斷。 四、驗(yàn)證這里就不貼圖了,驗(yàn)證發(fā)現(xiàn)已經(jīng)可以正常處理超長路徑了,不會再報(bào)錯(cuò)了。
五、開源因?yàn)镈otNetZip已經(jīng)不再積極維護(hù),且Nuget上的版本也標(biāo)記了棄用和風(fēng)險(xiǎn),所以也就不提PR了, 但在這么多壓縮解壓縮庫中,DotNetZip在易用性上是無與倫比的,所以在很多時(shí)候用用還是挺不錯(cuò)的。也基于此想法,正好也將自己之前封裝的方法給開源了吧,基于DotNetZip,就兩個(gè)方法:Zip、UnZip。簡單易用、解決了超長路徑(MAX_PATH)問題、支持密碼、分卷。 開源地址:https://gitee.com/lesliexin/lesliexin.simplezip NuGet:https://www.nuget.org/packages/LeslieXin.SimpleZip 六、結(jié)語這次也是遇到了這個(gè)超長路徑(MAX_PATH)的問題,才想起來修復(fù)下,順便也開源下自己的庫。 本篇文章最重要的是給讀者一個(gè)遇到超長路徑(MAX_PATH)問題時(shí)一個(gè)實(shí)操指導(dǎo),畢竟此問題不止會發(fā)生在DotNetZip中,可能發(fā)生在任何與文件路徑相關(guān)的地方,當(dāng)再次遇到此問題時(shí),該如何一步步去排查定位和處理。 ?轉(zhuǎn)自https://www.cnblogs.com/lesliexin/p/18930533 該文章在 2025/9/9 9:53:28 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |