[解決済み] ファイルパスが長すぎる例外を解決する最良の方法
質問
私はSPサイトのすべてのドキュメントライブラリをダウンロードするアプリを作成しましたが、ある時点でこのエラーが発生しました(Googleで探してみましたが、何も見つかりませんでした。)
System.IO.PathTooLongException: 指定されたパス、ファイル名、またはその両方が長すぎる。完全修飾ファイル名は 260 文字未満、ディレクトリ名は 248 文字未満でなければなりません。 at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck) at System.IO.Path.GetFullPathInternal(String path) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) at System.IO.FileStream.ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.File.Create(String path)
文字列の制限に達したため、以下にコードを示します。
#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
解決方法は?
エラーの原因が明らかであるため、問題解決に役立つ情報を紹介します。
こちらをご覧ください ファイル、パス、名前空間の命名に関するMSの記事
以下、リンク先からの引用です。
<ブロッククオートパスの最大長制限 Windows APIでは(以下の段落で説明する一部の例外を除き)、最大長は1.5mです。 は、MAX_PATH であり、これは 260 文字と定義されている。ローカル パスの構成は、ドライブレター、コロン、パスフレーズの順です。 バックスラッシュ、バックスラッシュで区切られた名前の構成要素、そして終端である ヌル文字。例えば、Dドライブの最大パスは "D:↵、Dドライブの最大パスは "↵です。 256文字のパス文字列<NUL>" ここで、"<NUL>"は不可視のパス文字列を表し、256文字のパス文字列を表します。 現在のシステムコードページの終端ヌル文字。(この 文字 < > は、ここでは視覚的にわかりやすくするために使用されており、その一部となることはできません。 は有効なパス文字列です)。
そして、いくつかの回避策(コメントから抜粋)。
様々な問題を解決する方法があります。以下に挙げる解決策の基本的な考え方は常に同じで、パス長を短縮して
path-length + name-length < MAX_PATH
. してもよい。
- サブフォルダーの共有
- コマンドラインからSUBSTでドライブレターを割り当てる。
- VBでAddConnectionを使用して、ドライブレターをパスに割り当てます。
関連
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] 複数行の長い文字列を作成するためのPythonicな方法
-
[解決済み] C#で文字を繰り返し表示する最適な方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました