Windowsで256より長いパス名



Path Names Longer Than 256 Windows



解決:

いくつかのまれな例外を除いて、 Mathematica 通常、Windowsでは長いパス名を使用できません。この応答は、この問題を回避するための2つの戦略を示しています。 拡張長パス構文短いパス名 (Windows Dev Centerのファイル、パス、および名前空間の命名に記載されています)。

大きなファイル名から始めましょう:



$ big = '03456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903456789034567890345678903

拡張長パス構文

捨てた コマンドはこのビッグネームを処理できません:



Run ['cmd / c echo hello>'、$ big](* 1 *)(*つまり 'エラー' *)

ただし、拡張長パス構文を処理できます(最近のバージョンのWindows)。これは接頭辞を付けることを伴います\?絶対パス名の前に。いくつかのヘルパー関数を使用します。

$ longPrefix = '\\?\'; toLongPath [filename _]:= $ longPrefix ExpandFileName [filename] fromLongPath [filename _]:= StringReplace [filename、StartOfString ~~ $ longPrefix-> '']

使用法:

toLongPath [$ big](* \? C: Users  wreach  Documents  03456789 ... 9034567890 *)fromLongPath [%](* C: Users  wreach  Documents  03456789 ... 9034567890 *)

捨てた コマンドは次の構文を受け入れます。

Run ['cmd / c echo hello>'、toLongPath [$ big]](* 0 *)(*つまり 'success' *)FirstCase [FileNames []、n_ /; StringLength [n]> 200](* '03456789034567890345 ... 789034567890' *)

NS Mathematica CopyFile関数も次の構文を受け入れます。

CopyFile [toLongPath [$ big]、 'god']; FilePrint ['zot'](* hello *)DeleteFile ['zot']

短いパス名

不幸にも、FilePrintは、拡張長パス構文をサポートしていません。

FilePrint [toLongPath [$ big]](* \? C: Users  wreach  Documents  03456 ... 890を開くことができません。>> *)

2番目の戦略である短いパス名に切り替えます。これらは、WindowsがDOSのようなコンポーネントで使用するために提供する代替名です(Windowsエコシステムのほとんどを読んでください)。 Windowsを使用してファイルのショートパス名を表示できます dir / x 指図:

Import ['!cmd / c dir / x 03456 *'、 'Text'](* ... C: Users  wreach  Documentsのディレクトリ... 2015-10-24 14:33 8 034567〜1034567890。 ..3456789034567890 ... *)

ディレクトリリストは、の短いファイル名が$ bigは034567〜1。

FilePrint ['034567〜1'](*こんにちは*)

プログラムでそのような名前を取得するとよいでしょう。悲しいかな、 Mathematica 短いファイル名を取得するための組み込み関数はありません。 NETLinkを使用してWin32API関数GetShortPathNameを呼び出します。

Needs ['NETLink`'] InstallNET []; getLastError = DefineDLLFunction ['GetLastError'、 'kernel32.dll'、 'DWORD'、{}]; getShortPathNameW = DefineDLLFunction ['GetShortPathNameW'、 'kernel32.dll'、 'DWORD'、{'LPCTSTR'、 'System.Text.StringBuilder'、 'DWORD'}、MarshalStringsAs-> 'Unicode']; shortPath [name_String]:= NETBlock @ Module [{result = NETNew ['System.Text.StringBuilder'、260]}、getShortPathNameW [[email protected]、result、[email protected]]; getLastError [] /。 0:> [メール保護] @ToString []]

動作中のヘルパー関数は次のとおりです。

shortPath [$ big](* C: Users  wreach  DOCUME〜1  034567〜1 *)

この短いパスは、どこでも使用できます Mathematica 、 含むFilePrint:

FilePrint [shortPath [$ big]](* hello *)

このような短いパスは、サポートするすべてのコンポーネントでも使用できます。 Mathematica 、DLL、Java、コマンドラインツールなど。

短いパスは、すでに存在するファイルに対してのみ取得できることに注意してください。このメカニズムを使用して、大きな名前の新しいファイルを作成することはできません。


ちなみに、DeleteFileは、拡張長パス構文を受け入れる数少ない関数の1つです。

DeleteFile [toLongPath [$ big]] 

(上記のWReachによる素晴らしい答えへの追加。)

少なくともバージョン11.3以降 Mathematica 文書化されていない関数を使用して短いファイル名を取得する方法が組み込まれていますFileInformation:

Export ['Тест.txt'、 ''] FileInformation ['Тест.txt'、 'AbsoluteShortFileName'] 
'Тест.txt''D:\ DOCUME〜1 \ 47BB〜1.TXT'

(情報を提供してくれたGenericAccountNameに感謝します)。

また、バージョン12.0.0以降、短いパスを取得するための文書化されていない(ただし「公式」)方法があります。

Information [File ['Тест.txt']、 'Properties'] //浅い 
{'ObjectType'、 'FileName'、 'DirectoryName'、 'AbsoluteFileName'、 'AbsoluteShortFileName'、 'ShortFileName'、 'FileBaseName'、 'FileExtension'、 'C​​reationDate'、 'LastAccessDate'、<>}
情報[ファイル['Тест.txt']、 'AbsoluteShortFileName'] 
'D:\ DOCUME〜1 \ 47BB〜1.TXT'