C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

BinaryReader/Writerでのコピーが遅い

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■92467 / inTopicNo.1)  BinaryReader/Writerでのコピーが遅い
  
□投稿者/ take (3回)-(2019/09/28(Sat) 11:44:15)

分類:[C#] 

こんにちは
BinaryReader と BinaryWriter を使用してファイルコピーをした場合の
コピーにかかる時間についての質問となります。

C# .NET Framework 3.5

大きいバイナリファイル(16GB程)を BinaryReader と BinaryWriter を使用し
ローカルフォルダ から ネットワーク共有フォルダ へコピーしようとしていまが、
File.Copy や エクスプローラ でコピーするより大分遅いです。

File.Copy -> 12分
BinaryRead/Write -> 14〜16分
エクスプローラ -> 12分

BinaryRead/Writeを使用した場合、
File.Copy と同程度の速度を出す事はできないのでしょうか?


一度に読込するバイト数を変えると早くはなりますが、それでも14分強です。
(指定しなかった場合は16分、4MBにすると14分程になりました。)

以下、ソースです。

void main()
{
  copy(@"c:\16gb.dat", @"\\xxxx\hoge\16gb.dat");
}

void copy(stirng from, string to)
{
  using (var br = new BinaryReader(File.OpenRead(from)))
  {
    using (var bw = new BinaryWriter(File.OpenWrite(to)))
    {
      bw.BaseStream.SetLength(br.BaseStream.Length);

      int bufSize = 4 * 1024 * 1025;
      byte[] buf = new byte[bufSize];
      while (true)
      {
        buf = br.ReadBytes(bufSize);
        if (buf.Length == 0)
        {
          break;
        }
        bw.Write(buf, 0, buf.Length);
      }
    }
  }
}

引用返信 編集キー/
■92468 / inTopicNo.2)  Re[1]: BinaryReader/Writerでのコピーが遅い
□投稿者/ Hongliang (897回)-(2019/09/28(Sat) 11:58:21)
バイナリブロックをコピーするだけであれば、BinaryReader/BinaryWriterの出番はありません。
Streamを直接ReadしてWriteすればいいです。
典型的には以下のようなコードになります。

using (Stream src = File.Open(srcPath), dst = File.Open(dstPath))
{
    byte[] buffer = new byte[バッファサイズ];
    int read;
    while ((read = src.Read(buffer, 0, buffer.Length)) > 0)
    {
        dst.Write(buffer, 0, read);
    }
}

引用返信 編集キー/
■92469 / inTopicNo.3)  Re[2]: BinaryReader/Writerでのコピーが遅い
□投稿者/ キングダム (45回)-(2019/09/28(Sat) 12:47:46)
ファイルのIOって割とネイティブコードとマネージコードの差が出るところなので
頑張ってるほうじゃないかなと思いました

File.Copyはネイティブコードに丸投げしますが
BinaryReader, BinaryWriterだとマネージコードからネイティブコードを
何度も呼ぶ形なので遅くなるだろうなーと思いました
引用返信 編集キー/
■92473 / inTopicNo.4)  Re[1]: BinaryReader/Writerでのコピーが遅い
□投稿者/ Azulean (1086回)-(2019/09/29(Sun) 12:51:42)
No92467 (take さん) に返信
>       byte[] buf = new byte[bufSize];
>       while (true)
>       {
>         buf = br.ReadBytes(bufSize);

BinaryReader.ReadBytes を呼ぶごとに 4MB 強の配列確保し、GC で開放されるというループのようなので、
byte[] を事前確保した FileStream.Read/Write と比較すると、相対的に遅くなる要素はありそうですね。


あと考えられるとしたら、BinaryReader/FileStream ともにメモリに一度コピーしてしまっている分、遅くなりそう。
純粋なファイルコピー処理は、やったとしてもファイルマッピングのような気もするので。

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ