2016-04-18 7 views
0

WindowsのPython 2.7.8でos.walk()と問題があります。UNCパスを使用している場合、os.walk()はサブディレクトリを処理していません

"D:\Test\master"などの「通常の」パスを入力すると、期待どおりに動作します。しかし、私は"\\?\D:\Test\master"のようなUNCパスを提供すると、期待どおりにルートディレクトリを報告しますが、サブディレクトリにドリルダウンしたり、例外を発生させたりしません。

私の研究:help pageで、os.walk()がエラーを処理するための関数引数を受け入れることを読んだ。デフォルトでは、この引数はNoneなので、エラーは報告されません。

私は単純な関数を渡してエラーを表示し、すべてのディレクトリに対して以下を受け取りました。

def WalkError(Error): 
    raise Exception(Error) 

スタックトレース:(元々の質問に編集として掲載)原作者から

Traceback (most recent call last): 
    File "Compare.py", line 988, in StartServer 
    for root, dirs, files in os.walk(ROOT_DIR,True,WalkError): 
    File "C:\Program Files (x86)\Python2.7.8\lib\os.py", line 296, in walk 
    for x in walk(new_path, topdown, onerror, followlinks): 
    File "C:\Program Files (x86)\Python2.7.8\lib\os.py", line 281, in walk 
    onerror(err) 
    File "Compare.py", line 62, in WalkError 
    raise Exception(Error) 
Exception: [Error 123] The filename, directory name, or volume label syntax is incorrect: '\\\\?\\D:\\Test\\master\\localization/*.*' 
+3

あなたが実際にあなた自身の質問への答えを投稿することができます。 http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ – Arthur2e5

+0

'' \\?\ ''接頭辞はUNCパスではありません。 '\\ server \ share'のようなUNCパスは拡張パス接頭辞を使って' \\?\ UNC \ server \ share'になります。この '' \\?\ ''接頭辞は、通常のパス処理をバイパスします。 Windowsは単に、これをNT DOSデバイスの接頭辞 '' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ''で置き換えます。これは、ログオンセッションのDOSデバイス内のデバイスのオブジェクトマネージャー検索と '\ Global ??'これは、NTパスがUnicodeなので、 '\\?\' 'パスは' unicode'文字列でなければならないことを意味し、フォワードスラッシュはNT名前空間内の通常の名前文字に過ぎないのでパスの区切り文字としてバックスラッシュのみを使わなければなりません。 – eryksun

+0

「//?/ D:/ Test/master」を使用すると、通常のパス処理をバイパスせず、パスは 'MAX_PATH'(260)文字に制限されます。 'u '\\\\?\\ D:\\ Test \\ master''を使用してください。 – eryksun

答えて

0

回答:

インスタントアップデート:\lib\os.pyを検査する過程で、私が発見エラーはos.listdir()に由来します。私はos.listdir()に関する上記のエラーメッセージを検索し、私のために働いたthis solutionが見つかりました。

UNCスタイルのパスを使用してUnix化する必要があるようです(\/に変換)。 \\\\?\\D:\\Test\\master\\//?/D:/Test/master/になります(注意:\は便利です)。

これは、UNC 'spec'と相殺されるので、MicrosoftのUNC実装を尊重する他のモジュールを使用している場合は注意してください。

(自己解決のために申し訳ありませんが、私はタブを閉じるには行くが、他の場所で見つけることができませんでしたここに知識があったと感じました。)

+0

UNCパスにはこのような問題はなく、 '\\?\' '接頭辞はUNCパスでもありません。 NTパスのパス区切り文字としてスラッシュを使うことはできません。これはPythonが8ビットの 'str'ブランチに' /*.* 'を追加して違反します。 '\ *。* 'を付けると' '\\?' 'を使うことができます。\ "は、unicodeの文字列ではないパスに書かれていますが、古いバージョンのWindowsでは8ビットのANSI文字列をこの制限を課す静的に割り当てられたバッファにデコードするため、最大260文字まで使用できます。とにかく、Pythonの 'listdir'の8ビット文字列ブランチは、260文字に制限されたスタック割り当てバッファを使用します。 – eryksun

+0

@eryksun私はこの答えを管理していない、私はそれを信用していない、私はこれを書かなかった。レビューキューで削除されたとマークされていたので、OPを手助けしたようだったので、単にそれを回収しました。編集してもよければ、自分の答えを投稿しても構いません。もしそうなら、私にこのことを削除できるように通知してください。ありがとう! :) – vacip

+0

私は関連する答え[ここ](http://stackoverflow.com/a/36237176/205580)と[ここ](http://stackoverflow.com/a/24064783/205580)です。 Python 2で '' \\?\ ''と 'listdir'を使って議論する別の答えを追加することもできますが、問題は8ビットの' str'パスで使用しようとすると発生します。 2.7では、Python 3ではWindowsのために 'bytes'パスが廃止されたのと同じです。 – eryksun

関連する問題