2015-03-10 2 views
0

J'ai un fichier de certificats PKCS # 7 (.spc) généré à partir de certains équipements. Il a un tableau de flottants, que j'ai besoin de lire dans mon programme C++.Comment puis-je lire un fichier .spc à partir de C++?

Avant, j'utilisais un programme externe pour générer un fichier .csv. Cependant, je perds une certaine précision ici car il ne sauvera que 15 chiffres. C'est un problème, j'ai besoin de la précision.

J'ai cherché pendant un certain temps, mais en vain. Essayer soit fstream ou un mmap boost donne quelques-uns charabia crypté ...

Comme ceci:

fstream:

fstream iofile; 
string path = "C:\\test.spc"; 
iofile.open(path.c_str()); 
if (iofile.is_open()) { 
    string s; 
    while (getline(iofile, s, '\n')) 
     cout << s << endl; 
} 

boost mmap:

boost::iostreams::mapped_file mmap("C:\\test.spc", boost::iostreams::mapped_file::readonly); // create RAM access mmap 
auto f = mmap.const_data(); // set data to char array 
auto l = f + mmap.size(); // used to detect end of file 
string next = ""; // used to read in chars 

for (; f && f != l; f++) { 
    cout << f[0] << endl; 
} 

Les deux caractères aléatoires juste sortie cela n'a aucun sens.

Nous avons découvert qu'il s'agit d'un format binaire. J'ai donc essayé ceci:

streampos size; 
char * memblock; 

ifstream file("C:\\test.spc", ios::in | ios::binary | ios::ate); 
if (file.is_open()) 
{ 
    size = file.tellg(); 
    memblock = new char[size]; 
    file.seekg(0, ios::beg); 
    file.read(memblock, size); 
    file.close(); 
    for (unsigned int i = 0; i < size; i++) 
     cout << memblock[i]; 
    cout << endl << "DONE" << endl; 
    cout << "the entire file content is in memory"; 

    delete[] memblock; 
} 
else cout << "Unable to open file"; 

Qui donne beaucoup plus de caractères qu'auparavant, mais toujours aléatoire.

Voici un lien vers le fichier: https://drive.google.com/a/uci.edu/file/d/0B3LD-8zOiOdza2FGSVNtbnlSVjQ/view?usp=sharing

+0

S'il vous plaît poster le code que vous avez essayé. Si c'est juste un fichier binaire de flottants, il devrait être trivial de le lire. –

+0

Code affiché ... ya il devrait être. CSV ne lit aucun problème, juste le SPC embêtant –

+0

Vous lisez dans les chaînes mais vous avez dit que votre fichier se compose de flotteurs. Est-ce que votre fichier est binaire ou texte? Pouvez-vous lier à la spécification de fichier? –

Répondre

1

SOLVED. Comme c'est un fichier binaire, j'ai essayé de trouver le format. Je l'ai trouvé, j'ai posté un lien avec des exemples de fichiers, du code, et le pdf expliquant le format pour tous ceux qui en ont besoin. Voici un code en C++ que j'ai écrit qui le lit. Merci à Spline Reticulated pour l'aide! https://drive.google.com/a/uci.edu/folderview?id=0B3LD-8zOiOdzfjY3YXJEdGlTZ2Z1ekJGNVlJalpYRmRkOHFFaFI4XzZEaWpFbldLSEt3LW8&usp=sharing

#include<stdio.h> 
#include <iostream> 
#include <iomanip> 
#include <map> 
using namespace std; 

//reads in SPC files according to "new" spc format. Advised to read pdf file, see link below 
//This shows how everything is set up, may not be entirely accurate depending on your implementation. 
//You can skip memory blocks to make codes shorter, this just shows you what each value represents. 
//See PDF for more details on each variable. https://drive.google.com/a/uci.edu/folderview?id=0B3LD-8zOiOdzfjY3YXJEdGlTZ2Z1ekJGNVlJalpYRmRkOHFFaFI4XzZEaWpFbldLSEt3LW8&usp=sharing 
// Also includes example spc file 
//Code is as is, I am not liable for any mishaps. 
//Open source, do whatever you want with it 
//Email for questions: [email protected] 

int main() 
{ 
FILE *ptr_myfile; 

// open file 
ptr_myfile = fopen("c:\\testspc.spc", "rb"); // "rb" to read binary, use "wb" to write binary 
if (!ptr_myfile) { 
    printf("Unable to open file!"); 
    return 1; 
} 

// variables used to store different mem sizes 
int i = 0;    // int, 4 bytes 
unsigned char b = 'a'; // byte, 1 byte 
double d = 0;   // double, 8 bytes 
float f = 0;   // float, 4 bytes 
short int w = 0;  // word, 2 bytes 

// variables we actually need 
int power2 = 0; // we use this to multiply to the y value (integer data value representing intensity) later 
int numDataPoints = 0; // used to divide first and last x coord, for increments in x values (wavenumbers) 
double firstXCoord = 0; // first logged x value (wavenumber) 
double lastXCoord = 0; // last logged x value (Wavenumber 
int numSubFiles = 1; 

// keep track of data 
// map< subfile#, map< wavenumber, intensity> > data 
map<int, map< double, long double> > data; 

// start main folder 
fread(&b, sizeof(b), 1, ptr_myfile); // flags represent different things (see pdf) 
fread(&b, sizeof(b), 1, ptr_myfile); // spc file version 
fread(&b, sizeof(b), 1, ptr_myfile); // experiment type code 
fread(&b, sizeof(b), 1, ptr_myfile); // IMPORTANT exponenet for Y values 
    power2 = (int)b; // save our exponent for multiplying 
fread(&i, sizeof(i), 1, ptr_myfile); // IMPORTANT number of points in file 
    numDataPoints = i; // keep this to divide my min and max x values 
fread(&d, sizeof(d), 1, ptr_myfile); // IMPORTANT first x coordinate 
    firstXCoord = d; // logs first x value (wavenumber) 
fread(&d, sizeof(d), 1, ptr_myfile); // IMPORTANT last x coordinate 
    lastXCoord = d; // logs last x value (wavenumber) 
fread(&i, sizeof(i), 1, ptr_myfile); // IMPORTANT Number of subfiles 
    numSubFiles = i; // keep track of how man spectra are being kept track of in this binary file 
fread(&b, sizeof(b), 1, ptr_myfile); // X units type code 
fread(&b, sizeof(b), 1, ptr_myfile); // Y units type code 
fread(&b, sizeof(b), 1, ptr_myfile); // Z units type code 
fread(&b, sizeof(b), 1, ptr_myfile); // Posting disposition 
fread(&i, sizeof(i), 1, ptr_myfile); // compressed date (see pdf for format) 
for (unsigned int j = 0; j < 9; j++) // resolution description text 
    fread(&b, sizeof(b), 1, ptr_myfile); 
for (unsigned int j = 0; j < 9; j++) // source instrument description text 
    fread(&b, sizeof(b), 1, ptr_myfile); 
fread(&w, sizeof(w), 1, ptr_myfile); // peak point number for interferograms 
for (unsigned int j = 0; j < 8; j++) // spare 
    fread(&f, sizeof(f), 1, ptr_myfile); 
for (unsigned int j = 0; j < 130; j++) // Memo 
    fread(&b, sizeof(b), 1, ptr_myfile); 
for (unsigned int j = 0; j < 30; j++) // x, y, and z custom axis strings (combined) 
    fread(&b, sizeof(b), 1, ptr_myfile); 
fread(&i, sizeof(i), 1, ptr_myfile); // byte offset to log block 
fread(&i, sizeof(i), 1, ptr_myfile); // file modification flag 
fread(&b, sizeof(b), 1, ptr_myfile); // processing code 
fread(&b, sizeof(b), 1, ptr_myfile); // calibration level + 1 
fread(&w, sizeof(w), 1, ptr_myfile); // sub method sample injection number 
fread(&f, sizeof(f), 1, ptr_myfile); // floatind data multiplier concentration factor 
for (unsigned int j = 0; j < 48; j++) // method file 
    fread(&b, sizeof(b), 1, ptr_myfile); 
fread(&f, sizeof(f), 1, ptr_myfile); // Z subfile increment for even Z multifiles 
fread(&i, sizeof(i), 1, ptr_myfile); // number of w planes 
fread(&f, sizeof(f), 1, ptr_myfile); // w plane increment 
fread(&b, sizeof(b), 1, ptr_myfile); // w axis units code 
for (unsigned int j = 0; j < 187; j++) // reserved 
    fread(&b, sizeof(b), 1, ptr_myfile); 
// end main header 

// do this for all subfiles 
for (unsigned int subFile = 0; subFile < numSubFiles; subFile++) { 
    // start sub folder for file (Even if only one file here) 
    fread(&b, sizeof(b), 1, ptr_myfile); // subfiles flags (See pdf) 
    fread(&b, sizeof(b), 1, ptr_myfile); // exponenet for sufiles y values 
    if ((int)b != 0) // my files at least had this area blank sinc had only one sub file 
     power2 = (int)b; // multiple sub files may have his changed, make sure to check other values for similar things 
    fread(&w, sizeof(w), 1, ptr_myfile); // subfile index number 
    fread(&f, sizeof(f), 1, ptr_myfile); // subfiels starting z value 
    fread(&f, sizeof(f), 1, ptr_myfile); // subfiles ending z value 
    fread(&f, sizeof(f), 1, ptr_myfile); // subfiles noise value to use peak picking 
    fread(&i, sizeof(i), 1, ptr_myfile); // number of points if XYXY multifile 
    fread(&i, sizeof(i), 1, ptr_myfile); // number of co-added scans 
    fread(&f, sizeof(f), 1, ptr_myfile); // w axis value 
    for (unsigned int j = 0; j < 4; j++) // reserved 
     fread(&b, sizeof(b), 1, ptr_myfile); 
    // end sub header for file 

    // get increment if just lists y values, and not in XY format 
    double increment = (lastXCoord - firstXCoord)/(numDataPoints-1); 
    double waveNumber = firstXCoord; 

    // start data entry for only x values 
    for (unsigned int j = 0; j < numDataPoints; j++) { 
     fread(&i, sizeof(i), 1, ptr_myfile); // read in data value 
     long double intensity = i * pow(2, power2)/(pow(2, 32)); // use pow(2, 16) in bottom fraction instead if data stored as 16-bit rather than 32-bit 
     data[subFile][waveNumber] = intensity; // store intensity 
     if (j <= 5) 
     cout << waveNumber << " = " << intensity << endl; 
     waveNumber += increment; // add increment to x value 
    } 
    // end data for x values 
} 

fclose(ptr_myfile); 
cout << "SPC FILE READ" << endl; 
int k; 
cin >> k; 
return 0; 
}