2011-07-22 27 views
3

あまりにも多くのRAMを必要とするプログラムのディスクI/O操作を実行したい。 私は倍精度の行列を使用し、バイトとしてのディスクへの書き込みが最も速い方法であると考えます(倍精度を維持する必要があります)。C++バイナリファイルからの倍数の書き込みと読み込み

移植性のある方法は?

私はこのコード(here)が見つかりましたが、著者は、それは可搬性でそれを行うにはどのように...

#include <iostream> 
#include <fstream> 

int main() 
{ 
    using namespace std; 

    ofstream ofs("atest.txt", ios::binary); 

    if (ofs) { 
     double pi = 3.14; 

     ofs.write(reinterpret_cast<char*>(&pi), sizeof pi); 
     // Close the file to unlock it 
     ofs.close(); 

     // Use a new object so we don't have to worry 
     // about error states in the old object 
     ifstream ifs("atest.txt", ios::binary); 
     double read; 

     if (ifs) { 
      ifs.read(reinterpret_cast<char*>(&read), sizeof read); 
      cout << read << '\n'; 
     } 
    } 

    return 0; 
} 
+2

'sizeof(double)'はプラットフォームによって異なる可能性があるため、移植性がありません。これをチェックする必要がありますが、そうでなければサンプルコードはOKです。 – spraff

+1

これは(特に組み込みハードウェアとやりとりしている場合に)変更される可能性が高いので、私は 'double'のバイトオーダーをもっと心配しています。 –

+0

真実は、話をして「可能性」の面で考えるのは悪い習慣です。ポータビリティについて本当に気にしているのであれば、その程度はありません。 – spraff

答えて

5

ポータブルではないと言っていますか?

異なる移植性のレベル/レベルがあります。これを1つのマシンに書き込んで同じものを読むだけであれば、このコードが明確に定義されているかどうかは、あなたが関係する唯一の移植性です。
複数の異なるプラットフォーム間で移植可能にする場合は、文字列の値をバイナリ値ではなく書く必要があります。

ただし、適切なエラー処理が不十分であることに注意してください。ファイルを開いて正常に書き込めるかどうかはチェックしません。

+0

あなたは答えに私を打ち負かしました:) –

+0

@ルチアン:非常に残念です。 ':)' – sbi

+0

私の "レベル"の移植性は、個人用のコンピュータ(WindowsおよびLinux/UNIX上)からクラスタへのものです。そして、最大のスピードと最小サイズが必要なので、私はバイトを書いています。 – Andy

2

私は移植性の問題は、ファイルに書き込んでそれを別のマシンで読むときにのみ発生すると思います。しかし、あなたはラムの制限のためにファイルを読み書きしたいと言っていたので、一度に1台のマシンで読み書き操作を行うと仮定できます。これはうまくいくはずです。

1

彼は、sizeofだけでなく、一般にバイナリ表現を指しているかもしれません。

C - Serialization of the floating point numbers (floats, doubles)

仕様は、すべての浮動小数点数のバイナリ表現を指定していません。 ほとんどのコンパイラはIEEEに準拠しているため、ターゲットプラットフォームが分かっている場合は、単体テストで動作を確認する必要があります。

+2

しかし、一部のマシンではリトルエンディアンのIEEEを使用し、一部のマシンではビッグエンディアンのIEEEフォーマットを使用していることを忘れないでください。おおよそIntelと他の人(PPC、SPARC、...)。 –

+0

はい、間違いありません。ポイントは、ターゲットとするすべてのプラットフォームで有効性を確認するためのテストを書く必要があるということです。 –

0

通常、ユニオンでバイトにアクセスします。

union Data { 
    double val; 
    unsigned char str[sizeof(double)]; 
}; 

void saveToFile(double *values, int nvalues, const char *filename){ 
    int i; 
    FILE *arq; 
    Data num; 

    arq=fopen(filename,"w"); 
    if (arq == NULL) { 
     printf("Failed to open file \"%s\"\n", filename); 
     exit(0); 
    } 

    for(i=0; i<nvalues; i++){ 
     num.val = values[i]; 
     fwrite (num.str , sizeof(char), sizeof(double), arq); //ChunkSize 
    } 

    fclose(arq); 
} 

void loadFromFile(double *values, int nvalues, const char *filename){ 
    int i; 
    FILE *arq; 
    Data num; 

    arq=fopen(filename,"r"); 
    if (arq == NULL) { 
     printf("Failed to open file \"%s\"\n", filename); 
     exit(0); 
    } 

    for(i=0; i<nvalues; i++){ 
     fread(num.str, sizeof(char), sizeof(double), arq); 
     values[i] = num.val; 
    } 

    fclose(arq); 
} 
+0

...この場合は暗黙の 'reinterpret_cast'を実行しているという事実を隠すための薄い単板です。このように、これは、OPによって要求されたものとまったく異なる、またはより移植性の高いものではありません。 'reinterpret_cast'をしなければならない場合は、正直で明示的に書いてください。 –

関連する問題