Fabien LE LEZ writes:On Tue, 6 Nov 2007 14:18:00 +0100, "Marc G" :char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on
ne sait pas dans quel ordre.
J'ai l'impression que tu te trompes. Tu peux m'indiquer quel
est ton raisonnement?
Fabien LE LEZ <grams...@gramster.com> writes:
On Tue, 6 Nov 2007 14:18:00 +0100, "Marc G" <mgueg...@metrica.fr>:
char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on
ne sait pas dans quel ordre.
J'ai l'impression que tu te trompes. Tu peux m'indiquer quel
est ton raisonnement?
Fabien LE LEZ writes:On Tue, 6 Nov 2007 14:18:00 +0100, "Marc G" :char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on
ne sait pas dans quel ordre.
J'ai l'impression que tu te trompes. Tu peux m'indiquer quel
est ton raisonnement?
On 06 Nov 2007 14:47:26 +0100, Jean-Marc Bourguet :char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on ne sa it pas
dans quel ordre.
J'ai l'impression que tu te trompes.
Avec un compilateur précis sur une plate-forme précise,
on peut savoir dans quel ordre les octets seront écrits.
Et sur plate-forme i386, je serais bien tenté d'affirmer que
les octets seront toujours écrits en commençant par l'octet de
poids faible.
Par ailleurs, sizeof(std::size_t) vaudra
probablement 4 sur un système 32 bits.
On 06 Nov 2007 14:47:26 +0100, Jean-Marc Bourguet <j...@bourguet.org>:
char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on ne sa it pas
dans quel ordre.
J'ai l'impression que tu te trompes.
Avec un compilateur précis sur une plate-forme précise,
on peut savoir dans quel ordre les octets seront écrits.
Et sur plate-forme i386, je serais bien tenté d'affirmer que
les octets seront toujours écrits en commençant par l'octet de
poids faible.
Par ailleurs, sizeof(std::size_t) vaudra
probablement 4 sur un système 32 bits.
On 06 Nov 2007 14:47:26 +0100, Jean-Marc Bourguet :char const* contents=UneChaine.data();
output.write((char*)&len,sizeof(std::size_t));
Résultat indéfini : les octets seront bien écrits, mais on ne sa it pas
dans quel ordre.
J'ai l'impression que tu te trompes.
Avec un compilateur précis sur une plate-forme précise,
on peut savoir dans quel ordre les octets seront écrits.
Et sur plate-forme i386, je serais bien tenté d'affirmer que
les octets seront toujours écrits en commençant par l'octet de
poids faible.
Par ailleurs, sizeof(std::size_t) vaudra
probablement 4 sur un système 32 bits.
On Tue, 6 Nov 2007 17:10:00 +0100, "Marc G" :Et la ça me pose un autre problème !
Par exemple j'ai écrit/lu des bool comme ça :
output.write((char*)&missing_,sizeof(missing_)); // missing_ est un bool
input.read((char*)&missing_,sizeof(missing_));
Quelle est la portabilité de ce code ?
Gloups... Je n'en ai pas la moindre idée.
La gestion en mémoire du type "bool" est un peu un mystère
pour moi, et je m'en porte très bien.
D'une manière générale, cette façon de faire n'offre aucune
garantie de portabilité, sauf bien sûr pour le type char.
Tu as pu voir qu'un format de fichier binaire est un peu
rock'n'roll à gérer. S'il n'y a pas trop de données, je
préfère largement un fichier texte ligne-par-ligne. C'est
lisible (et donc vérifiable et modifiable) directement avec un
éditeur de texte, les spécifications sont généralement plus
faciles à écrire, et le format s'avère souvent plus souple.
On Tue, 6 Nov 2007 17:10:00 +0100, "Marc G" <mgueg...@metrica.fr>:
Et la ça me pose un autre problème !
Par exemple j'ai écrit/lu des bool comme ça :
output.write((char*)&missing_,sizeof(missing_)); // missing_ est un bool
input.read((char*)&missing_,sizeof(missing_));
Quelle est la portabilité de ce code ?
Gloups... Je n'en ai pas la moindre idée.
La gestion en mémoire du type "bool" est un peu un mystère
pour moi, et je m'en porte très bien.
D'une manière générale, cette façon de faire n'offre aucune
garantie de portabilité, sauf bien sûr pour le type char.
Tu as pu voir qu'un format de fichier binaire est un peu
rock'n'roll à gérer. S'il n'y a pas trop de données, je
préfère largement un fichier texte ligne-par-ligne. C'est
lisible (et donc vérifiable et modifiable) directement avec un
éditeur de texte, les spécifications sont généralement plus
faciles à écrire, et le format s'avère souvent plus souple.
On Tue, 6 Nov 2007 17:10:00 +0100, "Marc G" :Et la ça me pose un autre problème !
Par exemple j'ai écrit/lu des bool comme ça :
output.write((char*)&missing_,sizeof(missing_)); // missing_ est un bool
input.read((char*)&missing_,sizeof(missing_));
Quelle est la portabilité de ce code ?
Gloups... Je n'en ai pas la moindre idée.
La gestion en mémoire du type "bool" est un peu un mystère
pour moi, et je m'en porte très bien.
D'une manière générale, cette façon de faire n'offre aucune
garantie de portabilité, sauf bien sûr pour le type char.
Tu as pu voir qu'un format de fichier binaire est un peu
rock'n'roll à gérer. S'il n'y a pas trop de données, je
préfère largement un fichier texte ligne-par-ligne. C'est
lisible (et donc vérifiable et modifiable) directement avec un
éditeur de texte, les spécifications sont généralement plus
faciles à écrire, et le format s'avère souvent plus souple.
Attention : tu es en train de confondre deux choses distinctes.
Que tu « écris » en mode texte ou en mode binaire dépend
uniquement de comment le fichier a été ouvert. Quand tu utilises
<< et >>, tu utilises un formattage texte pré-définit, mais si
le fichier a été ouvert en mode binaire, tu écris le résultat de
ce formattage toujours en mode binaire.
En l'occurance, les formats pré-définis ne supportent pas le
« round trip » ; les formats utilisés en sortie ne contient
pas assez d'informations pour être sûr de pouvoir retrouver les
données en entrée. (En particulier, ils ne comportent pas de
délimiteurs. Donc, si tu écris « output << i << j », ou i et j
sont des entiers, « input >> i >> j » ne te permettrait pas de
les rélire.) Le but des <<, c'est un formattage de présentation,
pour consumation humaine, et non la sérialisation.
Dans l'absence d'autres contraintes, j'aurais une tendance à
utiliser XDR -- c'est un format assez simple, mais qui a
l'avantage d'être déjà défini et spécifié, ce qui m'évite pas
mal de travail. Pour écrire en XDR, je ferais quelque chose du
genre :
oxdrstream&
oxdrstream::operator<<(
std::string const& obj )
{
assert( obj.size() <= 0xFFFFFFFF ) ;
sentry garde( *this ) ;
if ( garde ) {
*this << static_cast< uint32_t >( obj.size() ) ;
if ( obj.size() != 0 ) {
// Wraps streambuf writes with error
// checking, setting badbit if error, and
// doing nothing once error set...
GuardedSBuffer sb( rdbuf() ) ;
sb.puts( &obj[ 0 ], obj.size() ) ;
switch ( obj.size() % 4 ) {
case 1 :
sb.putc( ' ' ) ;
case 2 :
sb.putc( ' ' ) ;
case 3 :
sb.putc( ' ' ) ;
case 0 :
break ;
}
}
return *this ;
}
oxdrstream&
oxdrstream::operator<<(
uint32_t obj )
{
sentry garde( *this ) ;
if ( garde ) {
GuardedSBuffer sb( rdbuf() ) ;
sb.putc( obj >> 24 ) ;
sb.putc( obj >> 16 ) ;
sb.putc( obj >> 8 ) ;
sb.putc( obj ) ;
}
return *this ;
}
(Je ferais oxdrstream dériver de std::basic_ios<char>.)
Attention : tu es en train de confondre deux choses distinctes.
Que tu « écris » en mode texte ou en mode binaire dépend
uniquement de comment le fichier a été ouvert. Quand tu utilises
<< et >>, tu utilises un formattage texte pré-définit, mais si
le fichier a été ouvert en mode binaire, tu écris le résultat de
ce formattage toujours en mode binaire.
En l'occurance, les formats pré-définis ne supportent pas le
« round trip » ; les formats utilisés en sortie ne contient
pas assez d'informations pour être sûr de pouvoir retrouver les
données en entrée. (En particulier, ils ne comportent pas de
délimiteurs. Donc, si tu écris « output << i << j », ou i et j
sont des entiers, « input >> i >> j » ne te permettrait pas de
les rélire.) Le but des <<, c'est un formattage de présentation,
pour consumation humaine, et non la sérialisation.
Dans l'absence d'autres contraintes, j'aurais une tendance à
utiliser XDR -- c'est un format assez simple, mais qui a
l'avantage d'être déjà défini et spécifié, ce qui m'évite pas
mal de travail. Pour écrire en XDR, je ferais quelque chose du
genre :
oxdrstream&
oxdrstream::operator<<(
std::string const& obj )
{
assert( obj.size() <= 0xFFFFFFFF ) ;
sentry garde( *this ) ;
if ( garde ) {
*this << static_cast< uint32_t >( obj.size() ) ;
if ( obj.size() != 0 ) {
// Wraps streambuf writes with error
// checking, setting badbit if error, and
// doing nothing once error set...
GuardedSBuffer sb( rdbuf() ) ;
sb.puts( &obj[ 0 ], obj.size() ) ;
switch ( obj.size() % 4 ) {
case 1 :
sb.putc( ' ' ) ;
case 2 :
sb.putc( ' ' ) ;
case 3 :
sb.putc( ' ' ) ;
case 0 :
break ;
}
}
return *this ;
}
oxdrstream&
oxdrstream::operator<<(
uint32_t obj )
{
sentry garde( *this ) ;
if ( garde ) {
GuardedSBuffer sb( rdbuf() ) ;
sb.putc( obj >> 24 ) ;
sb.putc( obj >> 16 ) ;
sb.putc( obj >> 8 ) ;
sb.putc( obj ) ;
}
return *this ;
}
(Je ferais oxdrstream dériver de std::basic_ios<char>.)
Attention : tu es en train de confondre deux choses distinctes.
Que tu « écris » en mode texte ou en mode binaire dépend
uniquement de comment le fichier a été ouvert. Quand tu utilises
<< et >>, tu utilises un formattage texte pré-définit, mais si
le fichier a été ouvert en mode binaire, tu écris le résultat de
ce formattage toujours en mode binaire.
En l'occurance, les formats pré-définis ne supportent pas le
« round trip » ; les formats utilisés en sortie ne contient
pas assez d'informations pour être sûr de pouvoir retrouver les
données en entrée. (En particulier, ils ne comportent pas de
délimiteurs. Donc, si tu écris « output << i << j », ou i et j
sont des entiers, « input >> i >> j » ne te permettrait pas de
les rélire.) Le but des <<, c'est un formattage de présentation,
pour consumation humaine, et non la sérialisation.
Dans l'absence d'autres contraintes, j'aurais une tendance à
utiliser XDR -- c'est un format assez simple, mais qui a
l'avantage d'être déjà défini et spécifié, ce qui m'évite pas
mal de travail. Pour écrire en XDR, je ferais quelque chose du
genre :
oxdrstream&
oxdrstream::operator<<(
std::string const& obj )
{
assert( obj.size() <= 0xFFFFFFFF ) ;
sentry garde( *this ) ;
if ( garde ) {
*this << static_cast< uint32_t >( obj.size() ) ;
if ( obj.size() != 0 ) {
// Wraps streambuf writes with error
// checking, setting badbit if error, and
// doing nothing once error set...
GuardedSBuffer sb( rdbuf() ) ;
sb.puts( &obj[ 0 ], obj.size() ) ;
switch ( obj.size() % 4 ) {
case 1 :
sb.putc( ' ' ) ;
case 2 :
sb.putc( ' ' ) ;
case 3 :
sb.putc( ' ' ) ;
case 0 :
break ;
}
}
return *this ;
}
oxdrstream&
oxdrstream::operator<<(
uint32_t obj )
{
sentry garde( *this ) ;
if ( garde ) {
GuardedSBuffer sb( rdbuf() ) ;
sb.putc( obj >> 24 ) ;
sb.putc( obj >> 16 ) ;
sb.putc( obj >> 8 ) ;
sb.putc( obj ) ;
}
return *this ;
}
(Je ferais oxdrstream dériver de std::basic_ios<char>.)
Qu'est-ce qui se passe avec ta fonction sur un systèrme 64 bits ? seuls
les
32 bits de poids fort sont utilisés pour le codage des char, c'est ça ?
Peu importe ; c'est la cuisine interne du compilo (ou plutôt du
processeur).
J'ai un entier ; j'effectue 4 fois la division euclidienne par 256, et
j'enregistre les 4 restes successifs. C'est des maths ; ça n'a rien à
voir avec l'agencement de la RAM ou autre considération matérielle.
Tu as pu voir qu'un format de fichier binaire est un peu rock'n'roll à
gérer. S'il n'y a pas trop de données, je préfère largement un fichier
texte ligne-par-ligne. C'est lisible (et donc vérifiable et
modifiable) directement avec un éditeur de texte, les spécifications
sont généralement plus faciles à écrire, et le format s'avère souvent
plus souple.
Voir aussi un système de sérialisation, ce qui t'évitera de faire le
boulot toi-même. Celui de Boost par exemple.
http://www.boost.org/libs/serialization/doc/serialization.html
Qu'est-ce qui se passe avec ta fonction sur un systèrme 64 bits ? seuls
les
32 bits de poids fort sont utilisés pour le codage des char, c'est ça ?
Peu importe ; c'est la cuisine interne du compilo (ou plutôt du
processeur).
J'ai un entier ; j'effectue 4 fois la division euclidienne par 256, et
j'enregistre les 4 restes successifs. C'est des maths ; ça n'a rien à
voir avec l'agencement de la RAM ou autre considération matérielle.
Tu as pu voir qu'un format de fichier binaire est un peu rock'n'roll à
gérer. S'il n'y a pas trop de données, je préfère largement un fichier
texte ligne-par-ligne. C'est lisible (et donc vérifiable et
modifiable) directement avec un éditeur de texte, les spécifications
sont généralement plus faciles à écrire, et le format s'avère souvent
plus souple.
Voir aussi un système de sérialisation, ce qui t'évitera de faire le
boulot toi-même. Celui de Boost par exemple.
http://www.boost.org/libs/serialization/doc/serialization.html
Qu'est-ce qui se passe avec ta fonction sur un systèrme 64 bits ? seuls
les
32 bits de poids fort sont utilisés pour le codage des char, c'est ça ?
Peu importe ; c'est la cuisine interne du compilo (ou plutôt du
processeur).
J'ai un entier ; j'effectue 4 fois la division euclidienne par 256, et
j'enregistre les 4 restes successifs. C'est des maths ; ça n'a rien à
voir avec l'agencement de la RAM ou autre considération matérielle.
Tu as pu voir qu'un format de fichier binaire est un peu rock'n'roll à
gérer. S'il n'y a pas trop de données, je préfère largement un fichier
texte ligne-par-ligne. C'est lisible (et donc vérifiable et
modifiable) directement avec un éditeur de texte, les spécifications
sont généralement plus faciles à écrire, et le format s'avère souvent
plus souple.
Voir aussi un système de sérialisation, ce qui t'évitera de faire le
boulot toi-même. Celui de Boost par exemple.
http://www.boost.org/libs/serialization/doc/serialization.html
mes fichier comportent surtout des nombres, donc le mode binaire s'impose.
Le programme écrit des tables de données. Mon premier soucis est donc
que mes clients ne perdent pas leurs données !
Comme je vois que les fichiers binaires sont très rock'n'roll comme tu
dis, j'ai une idée et
j'aimerais que tu me dises ce que tu en penses : j'écris en début de
fichier la taille des différents types utilisés à l'écriture/lecture...
comme ça ne risque pas de dépasser 255, je peux même l'écrire
directement sur 1 octet.
Ensuite quand je veux relire le fichier, je commence par lire la taille
des types et je m'adapte...
Qu'en penses tu ?
mes fichier comportent surtout des nombres, donc le mode binaire s'impose.
Le programme écrit des tables de données. Mon premier soucis est donc
que mes clients ne perdent pas leurs données !
Comme je vois que les fichiers binaires sont très rock'n'roll comme tu
dis, j'ai une idée et
j'aimerais que tu me dises ce que tu en penses : j'écris en début de
fichier la taille des différents types utilisés à l'écriture/lecture...
comme ça ne risque pas de dépasser 255, je peux même l'écrire
directement sur 1 octet.
Ensuite quand je veux relire le fichier, je commence par lire la taille
des types et je m'adapte...
Qu'en penses tu ?
mes fichier comportent surtout des nombres, donc le mode binaire s'impose.
Le programme écrit des tables de données. Mon premier soucis est donc
que mes clients ne perdent pas leurs données !
Comme je vois que les fichiers binaires sont très rock'n'roll comme tu
dis, j'ai une idée et
j'aimerais que tu me dises ce que tu en penses : j'écris en début de
fichier la taille des différents types utilisés à l'écriture/lecture...
comme ça ne risque pas de dépasser 255, je peux même l'écrire
directement sur 1 octet.
Ensuite quand je veux relire le fichier, je commence par lire la taille
des types et je m'adapte...
Qu'en penses tu ?
sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
euh, là c'est trop compliqué pour moi... :-)))
euh, là c'est trop compliqué pour moi... :-)))
euh, là c'est trop compliqué pour moi... :-)))
On Wed, 7 Nov 2007 11:00:18 +0100, "Marc G" :sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
La question ici était d'enregistrer la taille d'une chaîne. Est-ce
qu'une chaîne de plus de 4 milliards de caractères a un sens dans ton
programme ?
M'enfin bon, comme je l'ai dit plus haut, commence par écrire les
spécifications de ton format de fichier. Ce sont elles qui
t'indiqueront la valeur de "NB_OCTETS".
On Wed, 7 Nov 2007 11:00:18 +0100, "Marc G" <mgueguen@metrica.fr>:
sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
La question ici était d'enregistrer la taille d'une chaîne. Est-ce
qu'une chaîne de plus de 4 milliards de caractères a un sens dans ton
programme ?
M'enfin bon, comme je l'ai dit plus haut, commence par écrire les
spécifications de ton format de fichier. Ce sont elles qui
t'indiqueront la valeur de "NB_OCTETS".
On Wed, 7 Nov 2007 11:00:18 +0100, "Marc G" :sauf que les entiers pourraient être codés sur 64 bits, avec une valeur max
supérieure, non ?
La question ici était d'enregistrer la taille d'une chaîne. Est-ce
qu'une chaîne de plus de 4 milliards de caractères a un sens dans ton
programme ?
M'enfin bon, comme je l'ai dit plus haut, commence par écrire les
spécifications de ton format de fichier. Ce sont elles qui
t'indiqueront la valeur de "NB_OCTETS".
Pour la place, c'est négligeable, mais ça se discute. Cela dépend de la
base de données et aussi de ce que tu ferais en binaire.
En général, si
on utilise le binaire, c'est pour concilier place et vitesse, ça suppose
donc qu'on étudie chaque champ, ses valeurs minimum et maximum, et donc
de ne pas se contenter d'écrire des int. Et pour la portabilité,
endianess, encodage et autre joyeusetés seront de la fête tôt ou tard...
tout un poême pour en tirer un avantage notable par rapport au mode texte !
Pour le temps machine sur la conversion, c'est négligeable aussi, et
même quasi-insignifiant si on lit les données sur un flux lent (à
l'échelle d'un programme C++, même les plus rapides des disque dûrs
fournissent des flux lents, une connexion réseau aussi).
Mais tout ça, à l'ère du XML/HTML à outrances avec plus de tags que de
données, c'est du pinaillage...
Pour la place, c'est négligeable, mais ça se discute. Cela dépend de la
base de données et aussi de ce que tu ferais en binaire.
En général, si
on utilise le binaire, c'est pour concilier place et vitesse, ça suppose
donc qu'on étudie chaque champ, ses valeurs minimum et maximum, et donc
de ne pas se contenter d'écrire des int. Et pour la portabilité,
endianess, encodage et autre joyeusetés seront de la fête tôt ou tard...
tout un poême pour en tirer un avantage notable par rapport au mode texte !
Pour le temps machine sur la conversion, c'est négligeable aussi, et
même quasi-insignifiant si on lit les données sur un flux lent (à
l'échelle d'un programme C++, même les plus rapides des disque dûrs
fournissent des flux lents, une connexion réseau aussi).
Mais tout ça, à l'ère du XML/HTML à outrances avec plus de tags que de
données, c'est du pinaillage...
Pour la place, c'est négligeable, mais ça se discute. Cela dépend de la
base de données et aussi de ce que tu ferais en binaire.
En général, si
on utilise le binaire, c'est pour concilier place et vitesse, ça suppose
donc qu'on étudie chaque champ, ses valeurs minimum et maximum, et donc
de ne pas se contenter d'écrire des int. Et pour la portabilité,
endianess, encodage et autre joyeusetés seront de la fête tôt ou tard...
tout un poême pour en tirer un avantage notable par rapport au mode texte !
Pour le temps machine sur la conversion, c'est négligeable aussi, et
même quasi-insignifiant si on lit les données sur un flux lent (à
l'échelle d'un programme C++, même les plus rapides des disque dûrs
fournissent des flux lents, une connexion réseau aussi).
Mais tout ça, à l'ère du XML/HTML à outrances avec plus de tags que de
données, c'est du pinaillage...