2

非常に長い名前のファイルから別の ntfs ストリームにアクセスする際に少し問題が発生します (このMAX_PATHに従って「\\?\」プレフィックスを使用して作成された文字数よりも長い)。初めてコードの間違いだと思ったのですが、cmdコマンドを試しました:

詳細 < "\\?\c:\!!!ロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングlong long long long long long long long long long ファイル名!!!.png:ストリーム名"

ファイルが見つからないというエラーで失敗します。ファイルが存在し、その内容を読み取ることができますが、読み取りと書き込みに必要なストリームにアクセスできません。私のソフトウェアが長いファイル名を扱えないようにしたくないので、この状況の回避策を探しています。

BackupRead functionを使用できることはわかっていますが、このソリューションが大きなファイルで高速になるかどうかはわかりません.2000年には機能しません.

GetShortPathName で同じ失敗結果が得られます。ファイル名を短縮できる API は他にありますか? 短いファイル名の一時ジャンクションを使用してこれを行いたくありません。何かご意見は?

4

1 に答える 1

6

ファイル名を指定するパラメーターをCreateFile参照すると、非常に役立つページに次のように記載されています。lpFileName

この関数の ANSI バージョンでは、名前は MAX_PATH 文字に制限されています。この制限を 32,767 ワイド文字に拡張するには、関数の Unicode バージョンを呼び出し、パスの前に "\?\" を追加します。

明らかに考えているので、BackupReadこのストリームにプログラムでアクセスしたいと考えています。その場合は、プログラムでテストしてください。コマンド プロンプトからこれらすべての操作を試みるのはクラック シュートであり、コマンド プロンプトからそのような操作を実行する能力以上のものを確立することはできません。

それを念頭に置いて、この単純なプログラムを試してみましょう - ボイラープレートコードは削除されました:

#include "stdafx.h"

int APIENTRY _tWinMain(HINSTANCE,
                       HINSTANCE,
                       LPTSTR,
                       int)
{
    /* This is the name of the file that we will try to create. Please note that
     * I have hardcoded the path to my user directory (C:\Users\nikb), and since 
     * it's unlikely that path exists on your computer, you should probably put
     * something there that makes sense.
     */
    LPCWSTR lpszFileName = L"\\\\?\\c:\\users\\nikb\\!!!Long long long long "
                           L"long long long long long long long long long long "
                           L"long long long long long long long long long long "
                           L"long long long long long long filename!!!.png:streamname";

    HANDLE hFile = CreateFileW(lpszFileName, GENERIC_WRITE, 0, NULL, 
        CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

    if(hFile != INVALID_HANDLE_VALUE)
    {
        BYTE bBuffer[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'N', 'i', 'k', '!' };
        DWORD dwSize = 10;

        if(WriteFile(hFile, bBuffer, dwSize, &dwSize, NULL))
            ::MessageBoxW(GetDesktopWindow(), L"Success", L"WriteFile", MB_OK);
        else
            ::MessageBoxW(GetDesktopWindow(), L"Failure", L"WriteFile", MB_OK);

        CloseHandle(hFile);
    }

    return 0;

}

これで問題なく動作するはずです。それでは、さらにいくつかの単語を追加して、そのファイル名を長くしましょう。繰り返しますが、マシンで有効なものへのパスを適切に更新してください。

LPCWSTR lpszFileName = L"\\\\?\\c:\\users\\nikb\\!!!Long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long long long long long long long long long long "
                       L"long long filename!!!.png:streamname";

さて、それは長いです。そして、それは失敗します。奇妙な...の出力を確認するGetLastError()ERROR_INVALID_NAME、何が得られるのでしょうか? 明らかに 32,767 文字より長くないため、これは機能するはずです。また、非常に長いパスを指定できるように凝った構文を使用しているためです\\?\。右?

うーん...ちょっと。Naming Files, Paths and NamespacesCreateFileというタイトルの非常に役立つページへのリンクに関する MSDN ページ。実際のところ、あなたも質問でそのページにリンクしています。あなたが質問する前にあなたの質問に答えていたので、これは興味深いです:

Windows API には、最大合計パス長 32,767 文字の拡張長パスを許可する Unicode バージョンもある多くの関数があります。このタイプのパスは 、バックスラッシュで区切られたコンポーネントで構成され、それぞれが GetVolumeInformation 関数の lpMaximumComponentLength パラメータで返される値までです (この値は通常 255 文字です)。拡張パスを指定するには、「\?\」プレフィックスを使用します。たとえば、「\?\D:\非常に長いパス」です。

したがって、パス自体の長さは 32,767 文字ですが、パスの個々のコンポーネント (つまり「部分」) は、ファイルシステムで許可されている最大値を超えることはできません。実際、NTFS が報告するコンポーネントの最大長を調べると、255 になります。

したがって、ファイル名は単一のコンポーネントであり、単一のコンポーネントは 255 文字を超えることはできません。指定したファイル名は次のとおりです。

!!!ロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングロングファイル名!!!.png:ストリーム名

簡単なテストでは、これが 264 文字の長さであることがわかります。当然のことながら、264 は 255 より大きいです。

于 2013-06-04T22:35:27.120 に答える