C ++でバイナリファイルを非常に高速に書き込む


240

SSD(ソリッドステートドライブ)に大量のデータを書き込もうとしています。そして膨大な量とは80GBを意味します。

私は解決策を求めてウェブを閲覧しましたが、私が思いついたのはこれでした:

#include <fstream>
const unsigned long long size = 64ULL*1024ULL*1024ULL;
unsigned long long a[size];
int main()
{
    std::fstream myfile;
    myfile = std::fstream("file.binary", std::ios::out | std::ios::binary);
    //Here would be some error handling
    for(int i = 0; i < 32; ++i){
        //Some calculations to fill a[]
        myfile.write((char*)&a,size*sizeof(unsigned long long));
    }
    myfile.close();
}

Visual Studio 2010と完全な最適化でコンパイルされ、Windows7で実行されるこのプログラムは、最大で約20MB / sです。本当に気になるのは、Windowsが他のSSDからこのSSDに150MB / sから200MB / sのどこかでファイルをコピーできることです。したがって、少なくとも7倍速くなります。だからこそ、もっと速く行けるようになるべきだと思います。

執筆をスピードアップする方法はありますか?


11
タイミングの結果から、a []を満たすまでの計算にかかる時間は除外されましたか?
catchmeifyoutry 2012

7
私は実際にこの仕事をしたことがある。simple fwrite()を使用すると、ピーク書き込み速度の約80%を得ることができました。それでFILE_FLAG_NO_BUFFERING初めて、最高速度を得ることができました。
ミスティシャル、

10
ファイルの書き込みをSSDからSSDへのコピーと比較するのが公平かどうかはわかりません。SSD-to-SSDがより低いレベルで機能し、C ++ライブラリを回避したり、ダイレクトメモリアクセス(DMA)を使用したりしている可能性があります。何かをコピーすることは、ランダムアクセスファイルに任意の値を書き込むことと同じではありません。
Igor F.

4
@IgorF .:それは間違った推測です。これは完全に公平な比較です(他に何もない場合は、ファイルの書き込みに有利です)。Windowsのドライブ間でのコピーは、読み取りと書き込みのみです。下で起こっている空想/複雑/異なるものは何もありません。
user541686 2012

5
@MaximYegorushkin:リンクまたはそれは起こりませんでした。:P
user541686

回答:


232

これは仕事をしました(2012年):

#include <stdio.h>
const unsigned long long size = 8ULL*1024ULL*1024ULL;
unsigned long long a[size];

int main()
{
    FILE* pFile;
    pFile = fopen("file.binary", "wb");
    for (unsigned long long j = 0; j < 1024; ++j){
        //Some calculations to fill a[]
        fwrite(a, 1, size*sizeof(unsigned long long), pFile);
    }
    fclose(pFile);
    return 0;
}

私は36秒で8 GBの時間を計っただけで、これは約220 MB /秒であり、SSDを使い果たしていると思います。また、注目に値するのは、問題のコードは1つのコアを100%使用したのに対し、このコードは2-5%しか使用していないことです。

皆様、本当にありがとうございました。

更新:2017年になって5年が経過しました。コンパイラ、ハードウェア、ライブラリ、および私の要件が変更されました。そのため、コードにいくつかの変更を加え、いくつかの新しい測定を行いました。

最初にコード:

#include <fstream>
#include <chrono>
#include <vector>
#include <cstdint>
#include <numeric>
#include <random>
#include <algorithm>
#include <iostream>
#include <cassert>

std::vector<uint64_t> GenerateData(std::size_t bytes)
{
    assert(bytes % sizeof(uint64_t) == 0);
    std::vector<uint64_t> data(bytes / sizeof(uint64_t));
    std::iota(data.begin(), data.end(), 0);
    std::shuffle(data.begin(), data.end(), std::mt19937{ std::random_device{}() });
    return data;
}

long long option_1(std::size_t bytes)
{
    std::vector<uint64_t> data = GenerateData(bytes);

    auto startTime = std::chrono::high_resolution_clock::now();
    auto myfile = std::fstream("file.binary", std::ios::out | std::ios::binary);
    myfile.write((char*)&data[0], bytes);
    myfile.close();
    auto endTime = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}

long long option_2(std::size_t bytes)
{
    std::vector<uint64_t> data = GenerateData(bytes);

    auto startTime = std::chrono::high_resolution_clock::now();
    FILE* file = fopen("file.binary", "wb");
    fwrite(&data[0], 1, bytes, file);
    fclose(file);
    auto endTime = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}

long long option_3(std::size_t bytes)
{
    std::vector<uint64_t> data = GenerateData(bytes);

    std::ios_base::sync_with_stdio(false);
    auto startTime = std::chrono::high_resolution_clock::now();
    auto myfile = std::fstream("file.binary", std::ios::out | std::ios::binary);
    myfile.write((char*)&data[0], bytes);
    myfile.close();
    auto endTime = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}

int main()
{
    const std::size_t kB = 1024;
    const std::size_t MB = 1024 * kB;
    const std::size_t GB = 1024 * MB;

    for (std::size_t size = 1 * MB; size <= 4 * GB; size *= 2) std::cout << "option1, " << size / MB << "MB: " << option_1(size) << "ms" << std::endl;
    for (std::size_t size = 1 * MB; size <= 4 * GB; size *= 2) std::cout << "option2, " << size / MB << "MB: " << option_2(size) << "ms" << std::endl;
    for (std::size_t size = 1 * MB; size <= 4 * GB; size *= 2) std::cout << "option3, " << size / MB << "MB: " << option_3(size) << "ms" << std::endl;

    return 0;
}

このコードは、Visual Studio 2017およびg ++ 7.2.0(新しい要件)でコンパイルされます。私は2つの設定でコードを実行しました:

  • ラップトップ、Core i7、SSD、Ubuntu 16.04、g ++バージョン7.2.0 -std = c ++ 11 -march = native -O3
  • デスクトップ、Core i7、SSD、Windows 10、Visual Studio 2017バージョン15.3.1、/ Ox / Ob2 / Oi / Ot / GT / GL / Gy

これにより、次の測定値が得られました(明らかな外れ値だったため、1MBの値を 破棄した後): option1とoption3の両方でSSDが最大になります。option2はかつて私の古いマシンで最速のコードであったため、これが表示されるとは思っていませんでした。ここに画像の説明を入力してください ここに画像の説明を入力してください

TL; DR:私の測定値はをstd::fstream超える使用を示していますFILE


8
+1ええ、これは私が最初に試したものでした。FILE*ストリームよりも高速です。とにかくI / Oにバインドされるべきだったので、私はそのような違いを期待していなかっただろう。
ミスティシャル、

12
CスタイルのI / Oが(奇妙なことに)C ++ストリームよりもはるかに高速であると結論付けることはできますか?
シェプリン

21
@SChepurin:あなたが知識を持っているなら、おそらくそうではありません。あなたが実用的であれば、おそらくはい。:)
user541686 2012

10
(私のようなC ++ dunceの場合)2つのアプローチの違いを説明してください。なぜこれが元のアプローチよりもはるかに速く機能するのですか?
Mike Chamberlain、

11
先頭に追加ios::sync_with_stdio(false);することで、ストリーム付きのコードに違いはありますか?このラインを使用することと使用しないことの大きな違いに興味があるのですが、コーナーケースをチェックするのに十分な速度のディスクがありません。そして、実際の違いがある場合。
Artur Czajka

24

以下を順番に試してください。

  • より小さいバッファサイズ。一度に〜2 MiBを書くのが良いスタートかもしれません。私の最後のラップトップでは、約512 KiBがスイートスポットでしたが、まだSSDでテストしていません。

    注:バッファが非常に大きいと、パフォーマンスが低下する傾向があることに気付きました。以前、512-KiBバッファの代わりに16-MiBバッファを使用すると速度が低下することに気づきました。

  • を使用して_open(または_topenWindowsで正しくなりたい場合)、ファイルを開き、を使用します_write。これはおそらく多くのバッファリングを回避しますが、確実ではありません。

  • CreateFileおよびのようなWindows固有の関数を使用しますWriteFile。これにより、標準ライブラリでのバッファリングが回避されます。


オンラインで投稿されたベンチマーク結果を確認します。適切なスループットを得るには、キューの深さが32以上の4kB書き込みか、512K以上の書き込みが必要です。
Ben Voigt 2012

@BenVoigt:ええ、512 KiBが私にとってスイートスポットだったと私は相関しています。:)
user541686 2012

はい。私の経験から、通常は小さいバッファーサイズが最適です。例外は、使用している場合ですFILE_FLAG_NO_BUFFERING-大きいバッファーの方が良い傾向があります。FILE_FLAG_NO_BUFFERINGかなりDMA だと思いますので。
ミスティシャル'19

22

std :: stream / FILE / deviceに違いはありません。バッファリングと非バッファリングの間。

また注意してください:

  • SSDドライブは、いっぱいになると速度が低下する(転送速度が低下する)傾向があります。
  • SSDドライブは、古くなるにつれて(動作しないビットのため)遅くなる(転送速度が遅くなる)傾向があります。

63秒でコードが実行されるのを見ています。
したがって、転送速度:260M / s(私のSSDはあなたのものよりもわずかに速く見えます)。

64 * 1024 * 1024 * 8 /*sizeof(unsigned long long) */ * 32 /*Chunks*/

= 16G
= 16G/63 = 260M/s

std :: fstreamからFILE *に移動しても増加しません。

#include <stdio.h>

using namespace std;

int main()
{
    
    FILE* stream = fopen("binary", "w");

    for(int loop=0;loop < 32;++loop)
    {
         fwrite(a, sizeof(unsigned long long), size, stream);
    }
    fclose(stream);

}

したがって、C ++ストリームは、基盤となるライブラリで可能な限り高速に動作します。

しかし、OSをOSの上に構築されたアプリケーションと比較するのは不公平だと思います。アプリケーションは仮定を立てることができず(ドライブがSSDであることを認識していない)、転送にOSのファイルメカニズムを使用します。

ただし、OSは想定を行う必要はありません。関係するドライブのタイプを判別し、データ転送に最適な手法を使用できます。この場合、メモリからメモリへの直接転送。メモリ内のある場所から別の場所に80Gをコピーするプログラムを書いてみて、それがどれほど高速かを確認してください。

編集する

より低いレベルの呼び出しを使用するようにコードを変更しました
。つまり、バッファリングを行いません。

#include <fcntl.h>
#include <unistd.h>


const unsigned long long size = 64ULL*1024ULL*1024ULL;
unsigned long long a[size];
int main()
{
    int data = open("test", O_WRONLY | O_CREAT, 0777);
    for(int loop = 0; loop < 32; ++loop)
    {   
        write(data, a, size * sizeof(unsigned long long));
    }   
    close(data);
}

これは違いがありませんでした。

:通常のドライブを使用している場合、私のドライブはSSDドライブです。上記の2つの方法の違いが見られる場合があります。しかし、私が予想したように、非バッファリングとバッファリング(バッファサイズより大きい大きなチャンクを書き込む場合)は違いを生じません。

編集2:

C ++でファイルをコピーする最速の方法を試しましたか

int main()
{
    std::ifstream  input("input");
    std::ofstream  output("ouptut");

    output << input.rdbuf();
}

5
反対投票はしませんでしたが、バッファサイズが小さすぎます。OPが使用しているのと同じ512 MBのバッファーを使用してそれを実行しましたFILE*。ストリームでは20 MB /秒でしたが、では90 MB /秒です。
ミスティシャル、

また、fwrite(a、sizeof(unsigned long long)、size、stream); fwrite(a、1、size * sizeof(unsigned long long)、pFile);の代わりに 書き込みごとに64MBのチャンクで220MB / sをくれます。
ドミニク

2
@Mysticial:驚いたことに、バッファサイズが違います(私はあなたを信じています)。バッファーは、大量の小さな書き込みがあり、基礎となるデバイスが多くの要求に悩まされないようにする場合に役立ちます。ただし、巨大なチャンクを書き込んでいる場合は、(ブロッキングデバイスで)書き込み/読み取りを行うときにバッファを使用する必要はありません。そのため、データは直接基盤となるデバイスに渡される必要があります(したがって、バッファーをバイパスします)。ただし、違いが見られる場合は、これと矛盾し、書き込みが実際にバッファを使用している理由を不思議に思います。
マーティンヨーク

2
最善の解決策はありませバッファサイズを増やすことが、バッファを削除して、書き込みが根底にあるデバイスに直接データを渡すようにします。
マーティンヨーク

1
@Mysticial:1)小さなチャンクはありません=>(この例では)常に十分な大きさです。この場合、チャンクは512Mです2)これはSSDドライブ(私のものとOPの両方)なので、それは関係ありません。回答を更新しました。
マーティンヨーク

13

最善の解決策は、ダブルバッファリングで非同期書き込みを実装することです。

タイムラインを見てください:

------------------------------------------------>
FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|

「F」はバッファの充填時間を表し、「W」はバッファをディスクに書き込む時間を表します。したがって、バッファをファイルに書き込む間の時間を浪費する際の問題。ただし、別のスレッドに書き込みを実装することにより、次のようにすぐに次のバッファーへの書き込みを開始できます。

------------------------------------------------> (main thread, fills buffers)
FF|ff______|FF______|ff______|________|
------------------------------------------------> (writer thread)
  |WWWWWWWW|wwwwwwww|WWWWWWWW|wwwwwwww|

F-1番目のバッファを埋める
f-2番目のバッファを埋める
W-1番目のバッファをファイルに書き込む
w-2番目のバッファをファイルに書き込む
_-操作が完了するまで待機する

バッファスワップを使用したこのアプローチは、バッファを埋めるのに複雑な計算が必要な場合(したがって時間がかかる場合)に非常に役立ちます。私は常に内部で非同期書き込みを非表示にするCSequentialStreamWriterクラスを実装しているので、エンドユーザー向けのインターフェイスにはWrite関数のみがあります。

また、バッファサイズはディスククラスタサイズの倍数である必要があります。そうしないと、単一のバッファーを2つの隣接するディスククラスターに書き込むことにより、パフォーマンスが低下します。

最後のバッファを書き込みます。
最後にWrite関数を呼び出すときは、現在のバッファーがいっぱいになっていることをディスクにも書き込む必要があることを確認する必要があります。したがって、CSequentialStreamWriterには、データの最後の部分をディスクに書き込むFinalize(最終バッファフラッシュ)などの別のメソッドが必要です。

エラー処理。
コードが2番目のバッファーへの書き込みを開始し、1番目のバッファーが別のスレッドで書き込まれているが、何らかの理由で書き込みが失敗している間、メインスレッドはその失敗を認識している必要があります。

------------------------------------------------> (main thread, fills buffers)
FF|fX|
------------------------------------------------> (writer thread)
__|X|

CSequentialStreamWriterのインターフェイスにWrite関数がboolを返すか、例外をスローするため、別のスレッドでエラーが発生したと仮定します。その状態を覚えておく必要があるため、次にメインスレッドでWriteまたはFinilizeを呼び出すと、メソッドはFalseまたは例外をスローします。また、障害の前にデータを書き込んだとしても、バッファの充填を停止した時点は問題ではありません。おそらくファイルが破損していて役に立たないでしょう。


3
I / Oを実行することは計算と並行することは非常に良い考えですが、Windowsではそれを実行するためにスレッドを使用しないでください。代わりに、I / O呼び出し中にスレッドの1つをブロックしない「オーバーラップI / O」を使用してください。つまり、スレッドの同期について心配する必要はほとんどありません(それを使用してアクティブなI / O操作があるバッファーにアクセスしないでください)。
Ben Voigt

11

ファイルマッピングを試すことをお勧めします。私mmapは以前、UNIX環境で使用していましたが、達成できる高いパフォーマンスに感銘を受けました


1
@nalply心に留めておくには、これはまだ機能的で効率的で興味深いソリューションです。
Yam Marcovic 2012

mmapの長所と短所について、stackoverflow.com / a / 2895799/220060をご覧ください。特に「ファイルへの純粋なシーケンシャルアクセスの場合、必ずしも優れたソリューションであるとは限りません[...]」また、stackoverflow.com / questions / 726471は、32ビットシステムでは、2または3 GB。-ちなみに、その答えに反対したのは私ではありません。
nalply

8

FILE*代わりに、あなたが得たパフォーマンスを測定することはできますか?fwrite/write代わりに使用するオプションは次のfstreamとおりです。

#include <stdio.h>

int main ()
{
  FILE * pFile;
  char buffer[] = { 'x' , 'y' , 'z' };
  pFile = fopen ( "myfile.bin" , "w+b" );
  fwrite (buffer , 1 , sizeof(buffer) , pFile );
  fclose (pFile);
  return 0;
}

を使用する場合はwrite、同様のことを試してください。

#include <unistd.h>
#include <fcntl.h>

int main(void)
{
    int filedesc = open("testfile.txt", O_WRONLY | O_APPEND);

    if (filedesc < 0) {
        return -1;
    }

    if (write(filedesc, "This will be output to testfile.txt\n", 36) != 36) {
        write(2, "There was an error writing to testfile.txt\n", 43);
        return -1;
    }

    return 0;
}

また、調査することをお勧めしますmemory map。それがあなたの答えかもしれません。一度20GBのファイルを他のデータベースで処理してデータベースに保存する必要がありました。したがって、moemoryマップを使用することに関するソリューション。私はそれをしましPythonた。


実際、FILE*同じ512 MBのバッファを使用する元のコードの単純な同等物は、フルスピードになります。現在のバッファが小さすぎます。
ミスティシャル、

1
@Mysticialしかし、それは単なる例です。
cybertextron

ほとんどのシステムで2は、標準エラーに対応しますが、STDERR_FILENOではなくを使用することをお勧めします2。もう1つの重要な問題は、発生する可能性のある1つのエラーは、割り込み信号を受信したときのEINTRであり、これは実際のエラーではないため、単純に再試行する必要があることです。
ペイマン

6

open()/ write()/ close()APIコールを使用して、出力バッファーサイズを試してみてください。つまり、「many-many-bytes」バッファー全体を一度に渡すのではなく、2、3回書き込みを行います(TotalNumBytes / OutBufferSize)。OutBufferSizeは、4096バイトからメガバイトにすることができます。

別の試み-WinAPI OpenFile / CreateFileを使用し、このMSDNの記事を使用してバッファリングをオフにします(FILE_FLAG_NO_BUFFERING)。また、このMSDNのWriteFile()に関する記事では、ドライブのブロックサイズを取得して最適なバッファーサイズを知る方法を示しています。

とにかく、std :: ofstreamはラッパーであり、I / O操作がブロックされる可能性があります。Nギガバイトの配列全体をトラバースする場合にも時間がかかることに注意してください。小さなバッファを書き込んでいる間、それはキャッシュに到達し、より速く動作します。


6

fstreams自体はCストリームほど遅くはありませんが、CPUをより多く使用します(特にバッファリングが適切に構成されていない場合)。CPUが飽和すると、I / Oレートが制限されます。

少なくともMSVC 2015の実装では、ストリームバッファーが設定されていない場合、一度1文字が出力バッファーにコピーされます(を参照streambuf::xsputn)。したがって、必ずストリームバッファ(> 0)を設定してください

次のfstreamコードを使用して、書き込み速度を1500MB / s(私のM.2 SSDの最大速度)にすることができます。

#include <iostream>
#include <fstream>
#include <chrono>
#include <memory>
#include <stdio.h>
#ifdef __linux__
#include <unistd.h>
#endif
using namespace std;
using namespace std::chrono;
const size_t sz = 512 * 1024 * 1024;
const int numiter = 20;
const size_t bufsize = 1024 * 1024;
int main(int argc, char**argv)
{
  unique_ptr<char[]> data(new char[sz]);
  unique_ptr<char[]> buf(new char[bufsize]);
  for (size_t p = 0; p < sz; p += 16) {
    memcpy(&data[p], "BINARY.DATA.....", 16);
  }
  unlink("file.binary");
  int64_t total = 0;
  if (argc < 2 || strcmp(argv[1], "fopen") != 0) {
    cout << "fstream mode\n";
    ofstream myfile("file.binary", ios::out | ios::binary);
    if (!myfile) {
      cerr << "open failed\n"; return 1;
    }
    myfile.rdbuf()->pubsetbuf(buf.get(), bufsize); // IMPORTANT
    for (int i = 0; i < numiter; ++i) {
      auto tm1 = high_resolution_clock::now();
      myfile.write(data.get(), sz);
      if (!myfile)
        cerr << "write failed\n";
      auto tm = (duration_cast<milliseconds>(high_resolution_clock::now() - tm1).count());
      cout << tm << " ms\n";
      total += tm;
    }
    myfile.close();
  }
  else {
    cout << "fopen mode\n";
    FILE* pFile = fopen("file.binary", "wb");
    if (!pFile) {
      cerr << "open failed\n"; return 1;
    }
    setvbuf(pFile, buf.get(), _IOFBF, bufsize); // NOT important
    auto tm1 = high_resolution_clock::now();
    for (int i = 0; i < numiter; ++i) {
      auto tm1 = high_resolution_clock::now();
      if (fwrite(data.get(), sz, 1, pFile) != 1)
        cerr << "write failed\n";
      auto tm = (duration_cast<milliseconds>(high_resolution_clock::now() - tm1).count());
      cout << tm << " ms\n";
      total += tm;
    }
    fclose(pFile);
    auto tm2 = high_resolution_clock::now();
  }
  cout << "Total: " << total << " ms, " << (sz*numiter * 1000 / (1024.0 * 1024 * total)) << " MB/s\n";
}

私は他のプラットフォーム(Ubuntuの、FreeBSDの)上でこのコードを試してみましたが、何のI / Oレート差に気づいていないが、CPU使用率は約8の違い:1(fstream使用8倍以上のCPU)。したがって、私が想像できることですが、私がより高速のディスクを使用すると、fstream書き込みはstdioバージョンよりも遅くなります。


3

メモリマップファイルを使用してください。


@Mehrdadしかし、なぜですか?それはプラットフォーム依存のソリューションだからですか?
qehgt

3
いいえ...それは高速のシーケンシャルファイル書き込みを行うために、一度に大量のデータを書き込む必要があるためです。(たとえば、2 MiBチャンクはおそらく良い出発点です。)メモリマップファイルでは粒度を制御できないため、メモリマネージャーがプリフェッチ/バッファリングを決定するものに翻弄されます。一般に、ReadFileシーケンシャルアクセスでは、通常の読み取り/書き込みなどと同じくらい効果的であるとは見たことがありませんが、ランダムアクセスの方が優れている場合があります。
user541686 2012

ただし、メモリマップされたファイルは、たとえばページングのためにOSによって使用されます。これは、データを読み書きするための(速度の点で)高度に最適化された方法だと思います。
qehgt '19

7
@Mysticial:人々は明らかに間違っている多くのことを「知っています」
Ben Voigt

1
@qehgt:どちらかと言えば、ページングは​​順次アクセスよりもランダムアクセスに対してはるかに最適化されています。1ページのデータの読み取りは、1回の操作で1メガバイトのデータを読み取るよりはるかに遅くなります
user541686 2012

3

エクスプローラでディスクAからディスクBに何かをコピーすると、WindowsはDMAを使用します。つまり、ほとんどのコピープロセスでは、CPUは基本的にディスクコントローラーにどこにデータを配置し、そこからデータを取得するかを指示するだけで、チェーン内のステップ全体を排除し、大量の移動に最適化されていないステップを実行します。データの-そして私はハードウェアを意味します。

あなたすることはCPUに多くのことを含みます。「a []を埋めるためのいくつかの計算」の部分を紹介したいと思います。これは必須だと思います。a []を生成し、次にa []から出力バッファー(fstream :: writeが行うこと)にコピーしてから、もう一度生成します。

何をすべきか?マルチスレッド化!(私はあなたがマルチコアプロセッサを持っていると思います)

  • フォーク。
  • 1つのスレッドを使用して[]データを生成する
  • もう一方を使用してa []からディスクにデータを書き込みます
  • 2つの配列a1 []とa2 []が必要で、それらを切り替える
  • スレッド間で何らかの同期が必要になります(セマフォ、メッセージキューなど)。
  • Mehrdadが述べたWriteFile関数のような、低レベルのバッファリングされていない関数を使用する

1

ファイルストリームに高速に書き込みたい場合は、読み取りバッファを大きくすることができます。

wfstream f;
const size_t nBufferSize = 16184;
wchar_t buffer[nBufferSize];
f.rdbuf()->pubsetbuf(buffer, nBufferSize);

また、ファイルに大量のデータを書き込むときは、物理的にではなく論理的にファイルサイズを拡張する方が高速な場合があります。これは、ファイルを論理的に拡張する場合、ファイルシステムが新しいスペースを書き出す前にゼロにしないためです。また、多くのファイルの拡張を防ぐために実際に必要なよりも論理的にファイルを拡張することも賢明です。論理ファイル拡張は、Windows でXFSシステムを呼び出すSetFileValidDataxfsctlXFS_IOC_RESVSP64XFSシステムでサポートすることによってサポートされます。


0

イムではgccで私のプログラムをコンパイルGNU / Linuxのmingwので勝利7とウィンXPと働いた良いです

私のプログラムを使用して80 GBのファイルを作成するには、33行を次のように変更します。

makeFile("Text.txt",1024,8192000);

プログラムを終了するとファイルが破棄され、実行中にファイルを確認します

あなたが望むプログラムを変更するだけです

最初の1つはWindowsプログラムで、2つ目はGNU / Linux用です

http://mustafajf.persiangig.com/Projects/File/WinFile.cpp

http://mustafajf.persiangig.com/Projects/File/File.cpp

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.