6

構造内に 4000000 を超える jpeg ファイルを取得した後、新しいファイルを追加する際に問題が発生しました。File.Copy は例外をスローします: ファイル システムの制限により、要求された操作を完了できませんでした。

解決策はありますか?

情報

コード

    public bool AddFile(Uri uri, string path, bool withDelete = false)
    {
        var sourceFilePath = path;
        var destinationFilePath = Path.GetFullPath(uri.LocalPath);

        try
        {
            if (!File.Exists(sourceFilePath))
            {
                sourceFilePath = Directory.EnumerateFiles(sourceFilePath).FirstOrDefault();
                destinationFilePath = Path.Combine(destinationFilePath, Path.GetFileName(sourceFilePath));
            }

            if (!Directory.Exists(Path.GetDirectoryName(destinationFilePath)))
                Directory.CreateDirectory(Path.GetDirectoryName(destinationFilePath));

            if (withDelete && File.Exists(destinationFilePath))
                File.Delete(destinationFilePath);

            File.Copy(sourceFilePath, destinationFilePath);

            return true;
        }
        catch (Exception exc)
        {
            ServiceCore.GetLogger().Error(exc);
            throw exc;
        }
    }

スタックトレース

    2013-03-28 14:10:48.3784[Info]: 47356388:Unive.NetService.SimpleServices.DocumentManagementSerivce..ctor: Entry
    2013-03-28 14:10:48.4740[Info]: Static:Unive.NetService.SimpleServices.DocumentManagementSerivce..ctor: Success
    2013-03-28 14:10:48.4899[Info]: 47356388:Unive.NetService.SimpleServices.DocumentManagementSerivce.UploadFile: Entry
    2013-03-28 14:11:26.3277[Error]: Exception
    Message:The requested operation could not be completed due to a file system limitation

    Source:mscorlib
    Stack Trace:   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
       at Unive.NetService.Business.SimpleFileClient.AddFile(Uri uri, String path, Boolean withDelete) in D:\Tag Prografix\Unive.NetService\Business\SimpleFileClient.cs:line 33
    TargetSite:Void WinIOError(Int32, System.String)
    2013-03-28 14:11:26.5029[Error]:                         47356388:Unive.NetService.SimpleServices.DocumentManagementSerivce.UploadFileException
    Message:The requested operation could not be completed due to a file system limitation

    Source:mscorlib
    Stack Trace:   at Unive.NetService.Business.SimpleFileClient.AddFile(Uri uri, String path, Boolean withDelete) in D:\Tag Prografix\Unive.NetService\Business\SimpleFileClient.cs:line 42
       at Unive.NetService.Business.FileService.UploadFile(Int64 fileId, String fileName, String path, Boolean isDiagram) in D:\Tag Prografix\Unive.NetService\Business\FileService.cs:line 80
       at Unive.NetService.SimpleServices.DocumentManagementSerivce.UploadFile(Int64 fileId, String fileName, String path) in D:\Tag Prografix\Unive.NetService\SimpleServices\DocumentManagementSerivce.asmx.cs:line 100
    TargetSite:Void WinIOError(Int32, System.String)
4

1 に答える 1

2

問題を回避するために、ディレクトリを分割して分割する必要があります。Windows は、何百万ものファイルがあるディレクトリを好みません。

この問題を回避するために、ファイルには常に db 行 ID (GUID) を使用して名前が付けられます。
最後の部分を除いて、GUID の各部分はディレクトリです。ID 02510b5a-a605-4a4e-b00a-f554998378a9 のファイルは、ディレクトリ 02510b5a/a605/4a4e/b00a/ に保存され、名前は f554998378a9 です。そのため、ID を使用するだけでファイルに直接アクセスでき、何百万ものファイルが多くのディレクトリに分割されています。

編集:ここに投稿して以来、私のソリューションについて気づいた点: In .NET Guid は、最初の部分が非常に頻繁に変更され、最後の部分がそれほど頻繁に (またはめったに) 変更されないように生成されます。上記のように分割を使用すると、多くの第 1 レベルのディレクトリが作成され、各サブディレクトリにサブディレクトリが 1 つだけになります。したがって、これでも多くの第 1 レベルのディレクトリが作成され、システムの制限に達する可能性もあります (どこにあるのかわかりません)。ただし、Windows は、同じディレクトリに 4 000 000 のサブディレクトリを持つことを好まないでしょう)。

解決策: 解決策は、ディレクトリを作成するときに Guid パーツに戻すことです。

例: この GUID02510b5a-a605-4a4e-b00a-f554998378a9では、ディレクトリf554998378a9\b00a\4a4e\a605とファイル名を使用する必要があります02510b5a

.NET Guid は現在の時刻を使用して生成されることに注意してください。そのため、ループで何百万もの Guid を作成すると、それらはすべて同じように見え (最初の部分だけが異なります)、私のソリューションを使用して同じディレクトリになります。

于 2013-04-08T19:40:08.350 に答える