11

このコードを使用して、ファイルからチャンクを抽出しています

// info is FileInfo object pointing to file
var percentSplit = info.Length * 50 / 100; // extract 50% of file
var bytes = new byte[percentSplit];
var fileStream = File.OpenRead(fileName);
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Dispose();
File.WriteAllBytes(splitName, bytes);

このプロセスをスピードアップする方法はありますか?

現在、530 MBのファイルの場合、約4〜5秒かかります。今回は改善できますか?

4

4 に答える 4

8

あなたの質問にはいくつかのケースがありますが、どれも言語に関連していません。

以下、気になる点

  • ソース/デスティネーション ファイルのファイル システムは何ですか?
  • 元のソース ファイルを保持しますか?
  • それらは同じドライブにありますか?

C# では、メソッドが内部的File.Copyに呼び出すよりも高速になる可能性はほとんどありません。ただし、パーセンテージが 50 であるため、次のコードは高速ではない可能性があります。ファイル全体をコピーし、宛先ファイルの長さを設定しますCopyFileWINAPI

var info=new FileInfo(fileName);
var percentSplit=info.Length*50/100; // extract 50% of file

File.Copy(info.FullName, splitName);
using(var outStream=File.OpenWrite(splitName))
    outStream.SetLength(percentSplit);

さらに、

  1. ファイル分割後に元のソースを保持しない
  2. 宛先ドライブはソースと同じです
  3. 暗号化/圧縮が有効なファイル システムを使用していない

次に、できる最善のことは、ファイルをまったくコピーしないことです。たとえば、ソース ファイルがFATまたはFAT32ファイル システムにある場合、できることは次のとおりです。

  1. ファイルの新しく分割された部分の新しいディレクトリ エントリ (エントリ) を作成します
  2. エントリがターゲット パーツのクラスタを指すようにする
  3. 各エントリに正しいファイル サイズを設定する
  4. クロスリンクをチェックし、それを避ける

ファイル システムがNTFSであった場合、仕様を調べるのに長い時間を費やす必要があるかもしれません。

幸運を!

于 2013-02-10T11:56:01.460 に答える
2
var percentSplit = (int)(info.Length * 50 / 100); // extract 50% of file
var buffer = new byte[8192];
using (Stream input = File.OpenRead(info.FullName))
using (Stream output = File.OpenWrite(splitName))
{
    int bytesRead = 1;
    while (percentSplit > 0 && bytesRead > 0)
    {
        bytesRead = input.Read(buffer, 0, Math.Min(percentSplit, buffer.Length));
        output.Write(buffer, 0, bytesRead);
        percentSplit -= bytesRead;
    }
    output.Flush();
}

フラッシュは必要ないかもしれませんが、害はありません。これは非常に興味深いものでした。ループをwhileではなくdo-while変更すると、パフォーマンスに大きな影響がありました。ILはそれほど速くないと思います。私の PC は元のコードを 4 ~ 6 秒で実行していましたが、添付のコードは約 1 秒で実行されているように見えました。

于 2013-02-25T18:27:57.967 に答える
0

数メガバイトのチャンクで読み書きすると、より良い結果が得られます。チャンクの大きさによっても性能が変わります。

FileInfo info = new FileInfo(@"C:\source.bin");
FileStream f = File.OpenRead(info.FullName);
BinaryReader br = new BinaryReader(f);

FileStream t = File.OpenWrite(@"C:\split.bin");
BinaryWriter bw = new BinaryWriter(t);

long count = 0;
long split = info.Length * 50 / 100;
long chunk = 8000000;

DateTime start = DateTime.Now;

while (count < split)
{
    if (count + chunk > split)
    {
        chunk = split - count;
    }

    bw.Write(br.ReadBytes((int)chunk));
    count += chunk;
}

Console.WriteLine(DateTime.Now - start);
于 2013-02-11T12:21:13.760 に答える
-1

この問題を回避する最も速い方法は、バイナリバッファファイル入力を使用することだと思います。

私はC#についてはあまり詳しくありませんが、ファイルの特定の部分に移動し、その部分からバッファリングされた入力を行うためのいくつかのバッファリング手法を調べることができます。

また、ネイティブバッファリング技術のためにWindowsAPIでC++を使用することに頼ったり、高速バッファリングメソッドを備えたライブラリを見つけることもできます。

私は他に多くを提案することはできません、うまくいけばこれが役立つでしょう。

于 2013-02-10T04:16:28.343 に答える