Convertir un fichier binaire pour utilsation en mysql

67geek67 Messages postés 5 Date d'inscription vendredi 21 août 2009 Statut Membre Dernière intervention 28 septembre 2009 - 21 août 2009 à 16:51
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 - 26 août 2009 à 11:19
Salut tout le monde,

J'utilise c pour une application industrielle. Je suis chef de projet, responsable d'une collecte de données sur des chaines de production. LEs données sont collectées, historisées et communiquées grace à un module appelé eWON. Le format du fichier est binaire (.bin), et est une image du système de fichiers du eWON. L'entreprise eWON n'inclus pas de support pour l'implémentation en c, mais elle fournit un petit bout de code en C:http://ewon.be/Download/TN/TN03_1.1_UK.pdf pour lire le fichier. Ce fichier, je veux le lire et prendre une partie des données pour l'introduire dans une base mysql. La chose est, je n'ai aucune idée du comment... Je reçois ce fichier à travers un ftp, et je ne le lis qu'une fois enregistré sur mon serveur, donc je n'ai pas besoin de le traduire en temps réel.

Comment faire?

Je suis vraiment un foetus en mysql, et un gamin de 3 ans en programmation c. J'ai besoin d'avoir la chose qui marche dans quelques jours seulement, SVP AIDEZ-MOI!!!!

6 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
22 août 2009 à 08:09
Salut,

J'ai survolé le document de ton lien, et il décrit très bien comment faire. Ton fichier contient simplement un header et des données, et un exemple montre comment les lire. Le header fait 8 octet. La partie "compliquée" ne fait que compter le nombre de champ data en récupérant la taille du fichier, en lui soustrayant la taille du header, et en divisant par la taille de la structure data.

C'est pas super bien codé par contre je trouve. Par exemple, le swab(), couteux, on pourrait s'en passer facilement. De même que l'allocation des deux buffers. Et il faudrait aussi s'assurer que le buffer est assez grand -> Vu la structure du fichier, il serait facile de le lire par morceau de la taille du buffer.

Il y a de multiples exemple d'utilisation de base mysql en C sur le web -> recherche google.

Il n'y a donc rien de bien compliquer, encore que pour un grand débutant, forcément...
Cependant on est pas ici pour faire le boulot des autres gratuitement.
Tu peux essayer d'embaucher quelqu'un, ou te tourner vers un site de prestation de service. Je crois qu'il y en a de spécialisés dans les relativement petits projets informatiques.

Si tu as une question précise par contre, n'hésite pas.
0
67geek67 Messages postés 5 Date d'inscription vendredi 21 août 2009 Statut Membre Dernière intervention 28 septembre 2009
23 août 2009 à 11:43
Entièrement d'accord avec toi rt15, je ne veux en aucun cas demander à d'autres de faire mon travail et récolter les lauriers ensuite, c'est clairement honteux. En fait dans la panique je me suis mal expliqué. J'ai ce bout de programme, et j'aurais aimé le faire fonctionner au moins. J'utilise code::blocks pour les tests. Et la chose qui se passe, c'est que je ne sais pas comment faire fonctionner ça. Dois-je mettre les déclarations bout à bout dans le même fichier que le gros bout de code? Comment appeler cette partie dans le main?
J'ai fait des essais, en lançant le gros bout dans le main, mais il bloque toujours au format du fichier In (normalement "file" déclaré plus loin) dans le premier bout de programme.
En fait mon aide demandée serait plus tôt. Une fois ces trois bout de code en main (pas main.c lol), comment les enregistrer? Fichier Header, non je ne pense pas... Et comment les écrire pour les compiler et executer tout simplement...?
0
67geek67 Messages postés 5 Date d'inscription vendredi 21 août 2009 Statut Membre Dernière intervention 28 septembre 2009
23 août 2009 à 11:53
Pardon je ne trouve pas comment éditer le message précédent. LA vraie erreur est "initializer element is not constant" après lui avoir demandé:
In = fopen("c:\\ircall.bin", "rb"); (oui le nouveau fichier s'appelle ircall.bin)
Et j'ai l'impression de bloquer sur qqch de bête, même si je ne suis pas un pro en C...
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
23 août 2009 à 21:38
Je salue tes efforts.
Cependant, programmer, c'est un peu plus que copier-coller du code.

Il est fondamental de connaître un minimum la syntaxe du langage de programmation concerné (-> cours ici).
Il faut que tu sois en mesure de parfaitement comprendre ce que fait la moindre ligne de code du pdf.
Et il ne faut pas tâtonner. Il faut commencer par décrire ce qu'on veut faire sur un bout de papier, pour ensuite le traduire en code.

Lors de l'écriture du code, il faut travailler de manière incrémentale. Par exemple, il faut que tu commences par compiler et faire un marcher un hello world. Puis tu ouvres le fichier en question avec fopen/flcose. Tu compiles et tu tests. Puis tu ajoute la lecture du header, dont tu affiches le contenu. Tu compiles et tu tests. Et ainsi de suite pour chaque fonctionnalité. Cela permet d'isoler les problèmes les uns des autres et de les traiter facilement. Il faut aussi que tu t'assures de la propreté et de l'indentation de ton code a chaque étape, sans te priver de revoir totalement la structure du code si nécessaire (Plutôt faire une fonction pour ceci ou cela, déplacer du code dans un autre fichier...).

Si tu travailles sous C::B/gcc, je te conseille aussi vivement d'activer les warnings qui détectent pas mal d'erreur. Au moins -Wall. -ansi et -pedantic sont sympas aussi même s'ils obligent de se priver de "nouveautés" du langage (Par exemple des commentaires en //).

J'ai l'impression que mon acrobat reader 8.0 lit mal le pdf... Manque la fin des portions de codes, surtout la fonction SwapBytesAndWords. Ou alors c'est le pdf qui est nul. J'ai retouché le code pour qu'il compile (En virant SwapBytesAndWords).
Et, je m'étais trompé, le swab est utile. Par contre elle a pas l'air franchement dispo sous windows. Elle fait le même boulot que SwapBytesAndWords, mais pour le header. Elle passe de big endian à little indian. Le passage dépend de la taille des données, et comme le header ne contient que des sur 16 bits, swab fonctionne parfaitement. Par contre, pour les données, il faut utiliser une fonction personnalisée.
Mais swab semble pas officiellement dispo sous gcc/windows. Donc reste ce warning que j'ai pas pris le temps de corriger.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

/* Strucuture de l'header */
typedef struct
{
  unsigned short VersionHi;
  unsigned short VersionLo;
  unsigned short dummy;
  unsigned short StructLen;
}
HistoricalHeader_t;

/* Structure d'un champ de données */
typedef struct
{
  time_t LogTime;
  unsigned short Msec;
  unsigned short IntraSecCounter;
  unsigned int InitValue:1;
  unsigned int TagId:31;
  float Value;
}
HistoricalRecord_t;

/* Header */
HistoricalHeader_t Header;
/* Données */
HistoricalRecord_t HstBuffer[100000];
char Buffer[1600000];

long FileSize(FILE *Stream)
{
  long CurPos, Length;
  CurPos = ftell(Stream);
  fseek(Stream, 0L, SEEK_END);
  Length = ftell(Stream);
  fseek(Stream, CurPos, SEEK_SET);
  return Length;
}

int ReadFile(char *FileName)
{
  FILE *In;
  long Len;
  if ((In fopen(FileName, "rb")) NULL)
  {
    fprintf(stderr, "Cannot open input file.\n");
    return 1;
  }
  Len = FileSize(In)-8;
  Len /= sizeof(HistoricalRecord_t);
  fread(&Header, 8, 1, In);
  swab((char*)&Header, (char*)&Header, 8);
  fseek(In, 8L, SEEK_SET);
  fread(Buffer, sizeof(HistoricalRecord_t), Len, In);
  fclose(In);
  return 0;
}

int main()
{
  ReadFile("toto");
  return 0;
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
67geek67 Messages postés 5 Date d'inscription vendredi 21 août 2009 Statut Membre Dernière intervention 28 septembre 2009
25 août 2009 à 16:22
Tu avais raison, le programme tel qu'il est présenté dans le pdf n'est pas le même que celui que j'ai eu dans mon document. Je te montre l'autre, après quelques modifs que j'ai faites, notamment les // que tu mentionnais par rapport aux warnings, ou bien des déclarations dans la boucle for (uniquement possible en c++):
#include <stdio.h>

#include <time.h>

#include <stdlib.h>

#include <string.h>


/* struct declaration*/
typedef struct
{
unsigned short VersionHi;
unsigned short VersionLo;
unsigned short dummy;
unsigned short StructLen;
}
HistoricalHeader_t;

typedef struct
{
time_t LogTime;
unsigned short Msec;
unsigned short IntraSecCounter;
unsigned int InitValue:1;
unsigned int TagId:31;
float Value;
}
HistoricalRecord_t;

/* variables declaration*/
HistoricalHeader_t Header;
HistoricalRecord_t HstBuffer[100000];
char Buffer[1600000];
/*---------------------------------------------------------------------------*/

long FileSize(FILE *Stream)
{
long CurPos, Length;
CurPos = ftell(Stream);
fseek(Stream, 0L, SEEK_END);
Length = ftell(Stream);
fseek(Stream, CurPos, SEEK_SET);
return Length;
}
/*---------------------------------------------------------------------------*/
void SwapBytesAndWords(char *Source, char *Dest, unsigned long Length)
{
long i;
unsigned short *WordSource, *WordDest;
unsigned short tmp;
WordSource = (unsigned short*) Source;
WordDest = (unsigned short*) Dest;
for(i=0;i<Length/2; i++)
{
tmp = *(WordSource+1);
*(WordDest+1) = *WordSource;
*WordDest = tmp;
WordSource += 2;
WordDest += 2;
}
swab(const void *Source,const void *Dest, Length);
}

/*---------------------------------------------------------------------------*/
int ReadFile(char *FileName)
{
FILE *In;
long Len;
if ((In fopen(FileName, "rb")) NULL)
{
fprintf(stderr, "Cannot open input file.\n");
return 1;
}
Len = FileSize(In)-8;
Len /= sizeof(HistoricalRecord_t);
HstLen = Len;
fread(&Header, 8, 1, In);
swab((char*)&Header, (char*)&Header, 8);
fseek(In, 8L, SEEK_SET);
fread(Buffer, sizeof(HistoricalRecord_t), Len, In);
SwapBytesAndWords((char*)Buffer, (char*)HstBuffer, sizeof(HistoricalRecord_t)*Len);
fclose(In);
return 0;
}

int main()

{

ReadFile("/home/guillaume/cprogramming/ircall.bin");

return 0;

}

Le problème que j'ai maintenant, c'est qu'il me dit qu'il y a une déclaration implicite de la fonction swab, alors que si je ne me trompe pas, elle fait bien partie du header string.h...
Qu'est-ce que tu en pense?
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
26 août 2009 à 11:19
Barf, peut être avec un :
#undef __STRICT_ANSI__
avant les #include...
Mais c'est moche.

Sinon faudrait recoder swab.

A l'arrache, elle doit ressembler à quelque chose comme ça :

void custom_swab(const char *from, char *to, size_t size)
{
  char tmp;
  int i;

  for (i = 0; i < size; i += 2)
  {
    tmp = from[i];
    to[i] = from[i + 1];
    to[i + 1] = tmp;
  }
}
0
Rejoignez-nous