二進制文件和文本文件是不同的文件類型,因此在創建等方式也是不一樣的
使用文件方式見下表:
"r"(只讀) 為輸入打開一個文本文件
"w"(只寫) 為輸出打開一個文本文件
"a"(追加) 為追加打開一個文本文件
"rb"(只讀) 為輸入打開一個二進制文件
"wb"(只寫) 為輸出打開一個二進制文件
"ab"(追加) 為追加打開一個二進制文件
"r+"(讀寫) 為讀/寫打開一個文本文件
"w+"(讀寫) 為讀/寫創建一個文本文件
"a+"(讀寫) 為讀/寫打開一個文本文件
"rb+"(讀寫) 為讀/寫打開一個二進制文件
"wb+"(讀寫) 為讀/寫創建一個二進制文件
"ab+"(讀寫) 為讀/寫打開一個二進制文件
void generateBin(string filename, int npattern ,int ninput, int noutput){ FILE* file; file = fopen(filename.c_str(), "w"); if (file == NULL) { throw runtime_error("network: could not open " + string(filename) + " for writing"); } fwrite(&npattern, sizeof(int), 1, file); fwrite(&ninput, sizeof(int), 1, file); fwrite(&noutput, sizeof(int), 1, file); float * input = new float[ninput]; float * output = new float[noutput]; float range = 1; for (int n = 0; n < npattern;n++){ for (int i = 0; i < ninput; i++){ input[i] = range * ((float)rand() / RAND_MAX - 0.5); } fwrite(input,sizeof(float),ninput,file); for (int o = 0; o < noutput; o++){ output[o] = range * ((float)rand() / RAND_MAX - 0.5); } fwrite(output, sizeof(float), noutput, file); } if (fclose(file) != 0) { throw runtime_error("network: error on saving to " + string(filename)); } delete input; delete output; } void readdata(){ int ninput =0; int noutput = 0; int npatterns = 0; size_t data_read = 0; float* inputs = new float[ninput]; float* targets = new float[noutput]; string filename = "data.bin"; FILE *file = fopen(filename.c_str(), "r"); if (file == NULL) throw runtime_error("Cannot open file " + filename + " for reading"); int ok = fread(&npatterns, sizeof(int), 1, file) && fread(&ninput, sizeof(int), 1, file) && fread(&noutput, sizeof(int), 1, file); cout << npatterns << " " << ninput << " " << noutput << endl; cout << "ninput is:" << ninput << endl; cout << "noutput is:" << noutput << endl; cout << "npatterns is:" << npatterns << endl; for (int i = 0; i < npatterns; i++) { cout << "load_patterns i:" << i << endl; data_read = fread(inputs, sizeof(float), ninput, file); cout << "need: " << ninput << " get: " << data_read << endl; if (data_read != ((size_t)ninput)) { cout << "Wrong file format " << endl; fclose(file); throw runtime_error("Wrong file format"); } data_read = fread(targets, sizeof(float), noutput, file); if (data_read != ((size_t)noutput)) { cout << "Wrong file format " << endl; fclose(file); throw runtime_error("Wrong file format"); } cout << "load_patterns i:" << i << endl; } delete inputs; delete targets; fclose(file); }
上面兩段程序,試圖創建一個二進制文件,並且向其中寫入data,並且再在其中讀出二進制數據。
但是運行的結果是錯誤的,
data_read 的數量小於ninput,原因是因為使用了文本文件的創建方式,但是確使用了二進制文件的操作。應該改為如下的代碼
void generateBin(string filename, int npattern ,int ninput, int noutput){ FILE* file; file = fopen(filename.c_str(), "wb"); if (file == NULL) { throw runtime_error("network: could not open " + string(filename) + " for writing"); } fwrite(&npattern, sizeof(int), 1, file); fwrite(&ninput, sizeof(int), 1, file); fwrite(&noutput, sizeof(int), 1, file); float * input = new float[ninput]; float * output = new float[noutput]; float range = 1; for (int n = 0; n < npattern;n++){ for (int i = 0; i < ninput; i++){ input[i] = range * ((float)rand() / RAND_MAX - 0.5); } fwrite(input,sizeof(float),ninput,file); for (int o = 0; o < noutput; o++){ output[o] = range * ((float)rand() / RAND_MAX - 0.5); } fwrite(output, sizeof(float), noutput, file); } if (fclose(file) != 0) { throw runtime_error("network: error on saving to " + string(filename)); } delete input; delete output; } void readdata(){ int ninput =0; int noutput = 0; int npatterns = 0; size_t data_read = 0; float* inputs = new float[ninput]; float* targets = new float[noutput]; string filename = "data.bin"; FILE *file = fopen(filename.c_str(), "rb"); if (file == NULL) throw runtime_error("Cannot open file " + filename + " for reading"); int ok = fread(&npatterns, sizeof(int), 1, file) && fread(&ninput, sizeof(int), 1, file) && fread(&noutput, sizeof(int), 1, file); cout << npatterns << " " << ninput << " " << noutput << endl; cout << "ninput is:" << ninput << endl; cout << "noutput is:" << noutput << endl; cout << "npatterns is:" << npatterns << endl; for (int i = 0; i < npatterns; i++) { cout << "load_patterns i:" << i << endl; data_read = fread(inputs, sizeof(float), ninput, file); cout << "need: " << ninput << " get: " << data_read << endl; if (data_read != ((size_t)ninput)) { cout << "Wrong file format " << endl; fclose(file); throw runtime_error("Wrong file format"); } data_read = fread(targets, sizeof(float), noutput, file); if (data_read != ((size_t)noutput)) { cout << "Wrong file format " << endl; fclose(file); throw runtime_error("Wrong file format"); } cout << "load_patterns i:" << i << endl; } delete inputs; delete targets; fclose(file); }