Vous n'êtes pas identifié(e).
Bonjours
Je met les nom de fichier dans une table, la base de donnée est en utf8 de même que le serveur
j'utilise la libpqxx pour faire cela en c++ , le tout sous debian squezz , posgres 8.4
l'utilisateur posgres (admin)
psql
postgres=# \encoding
UTF8
mon utilisateur
psql
ma_base=> \encoding
UTF8
Le problème surviens aux moment ou il rencontre:
/home/user/.jpilot/ManaDB.pd
on peux y voir après: Ma : un caractère ? en losange sur fond noire.
il faut évidement que je puisse placer cela dans la table. et en plus de manière identique ,car le nom peux être demander pour restaurer le nom du fichier.
j'ai vu sur le web que ce problème est très fréquent, tous partes du principes que le client et le serveur son pas en utf8.
ce bug est re-productible si sa intéresse : il faut installer le soft jpilot (utiliser pour les palm)
le lancer et aller voir ~/.jpilot
je colle le message d'erreur aux complet:
terminate called after throwing an instance of 'pqxx::data_exception'
what(): ERREUR: séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61
HINT: Cette erreur peut aussi survenir si la séquence d'octets ne correspond pas
au jeu de caractères attendu par le serveur, le jeu étant contrôlé par
« client_encoding ».
je précise aussi que je débute
Merci d'avance
Dernière modification par Sub (06/03/2012 03:14:37)
Sous debian squeez, nouveaux sur le forum
Hors ligne
Je ne crois pas que le problème vient du nom du fichier. Je suppose que votre programme essaie d'envoyer le contenu du fichier dans la base. Pour cela, il faut que l'encodage du contenu de ce fichier corresponde à l'encodage indiqué par la variable client_encoding. Celle-ci semble être UTF-8. Donc il existe dans ce fichier des caractères qui ne sont pas en UTF-8. Il faut donc d'abord corriger le fichier avant de continuer. Si tout le fichier est dans un autre encoding, dans ce cas, il faut changer le client_encoding pour indiquer l'encodage du fichier. Et il faut espérer que tous les caractères de ce fichier sont convertibles en UTF-8 sinon vous aurez le même genre de message.
Guillaume.
Hors ligne
Si c'est pour réaliser un logiciel de sauvegarde, passez en encodage C pour la base, c'est la seule solution simple pour ce genre de problème. C'est ce que nous avons fait avec le logiciel Bacula par exemple. Un fichier peut contenir vraiment n'importe quoi, il n'y a pas de validation des caractères. Par ailleurs, si vous êtes sous un Unix, par exemple, le nom du fichier peut être dans vraiment n'importe quelle locale, c'est les variables d'environnement LOCALE et LC_* qui déterminent l'interprétation du nom du fichier. Il se peut même que vous rencontriez des fichiers dans plusieurs encodages différents sur un système de fichiers sensé être en UTF8, si par exemple vous avez de vieux fichiers qui traînent d'avant la migration du système en UTF8, ou si vous avez un serveur ftp ou samba.
Marc.
Hors ligne
Je ne crois pas que le problème vient du nom du fichier. Je suppose que votre programme essaie d'envoyer le contenu du fichier dans la base. Pour cela, il faut que l'encodage du contenu de ce fichier corresponde à l'encodage indiqué par la variable client_encoding. Celle-ci semble être UTF-8. Donc il existe dans ce fichier des caractères qui ne sont pas en UTF-8. Il faut donc d'abord corriger le fichier avant de continuer. Si tout le fichier est dans un autre encoding, dans ce cas, il faut changer le client_encoding pour indiquer l'encodage du fichier. Et il faut espérer que tous les caractères de ce fichier sont convertibles en UTF-8 sinon vous aurez le même genre de message.
Merci pour votre réponse, pas possible de corriger le nom du fichier il est générer automatiquement par le logiciel qui s'en sert
Sous debian squeez, nouveaux sur le forum
Hors ligne
Si c'est pour réaliser un logiciel de sauvegarde, passez en encodage C pour la base, c'est la seule solution simple pour ce genre de problème. C'est ce que nous avons fait avec le logiciel Bacula par exemple. Un fichier peut contenir vraiment n'importe quoi, il n'y a pas de validation des caractères. Par ailleurs, si vous êtes sous un Unix, par exemple, le nom du fichier peut être dans vraiment n'importe quelle locale, c'est les variables d'environnement LOCALE et LC_* qui déterminent l'interprétation du nom du fichier. Il se peut même que vous rencontriez des fichiers dans plusieurs encodages différents sur un système de fichiers sensé être en UTF8, si par exemple vous avez de vieux fichiers qui traînent d'avant la migration du système en UTF8, ou si vous avez un serveur ftp ou samba.
Merci de m'avoir répondu
j'utilise la libpqxx pour le c++
c'est pas pour une sauvegarde, mai sa s'en rapproche.
http://pqxx.org/devprojects/libpqxx/doc … Reference/
je suis sous debian, effectivement , Cela peux être de n'importe qu'elle local. il n'y pas une solution, un type de donnée qui n'est pas interpréter par pgsql ?
Sous debian squeez, nouveaux sur le forum
Hors ligne
Si, bien sûr… il y a le bytea, tableau d'octets. Il est aussi fait pour ça. Mais un peu moins pratique à manipuler que du text, puisque ça peut contenir vraiment n'importe quoi
Marc.
Hors ligne
Si, bien sûr… il y a le bytea, tableau d'octets. Il est aussi fait pour ça. Mais un peu moins pratique à manipuler que du text, puisque ça peut contenir vraiment n'importe quoi
j'ai essayer avec ce type de champ le résulta est le même:, je doit convertir le text avant de l'envoiyer a posgresql en un format spécifique, ou la conversion ce fait d'elle même ?
Sous debian squeez, nouveaux sur le forum
Hors ligne
Oui, il faut protéger les caractères bizarres pour que ça passe en bytea: http://docs.postgresql.fr/9.1/datatype-binary.html (en fait, ce n'est pas le bytea qui râle, c'est la chaîne de caractère que vous saisissez, qui n'est pas une chaîne de caractère, puisque ne valide pas en UTF8)
Le plus simple, en termes de programmation, est d'escaper systématiquement (transformer la séquence d'octets en chaine de caractère préfixée par \)
Marc.
Hors ligne
Oui, il faut protéger les caractères bizarres pour que ça passe en bytea: http://docs.postgresql.fr/9.1/datatype-binary.html (en fait, ce n'est pas le bytea qui râle, c'est la chaîne de caractère que vous saisissez, qui n'est pas une chaîne de caractère, puisque ne valide pas en UTF8)
Le plus simple, en termes de programmation, est d'escaper systématiquement (transformer la séquence d'octets en chaine de caractère préfixée par \)
d'après ce que j'ai lu c'est mieux de les convertir en hexadécimal, de cette manière plus de problème d'échappement ?
sinon il faut que je regarde si je trouve un exemple avec la librairie que j'utilise.
Merci pour votre réponse
Sous debian squeez, nouveaux sur le forum
Hors ligne
C'est pas vraiment «convertir en hexadécimal», plutôt saisir le bytea sous forme de chaîne, avec un escaping hexadécimal. Mais oui, c'est la meilleure façon de faire, c'est l'escaping le plus performant.
Marc.
Hors ligne
C'est pas vraiment «convertir en hexadécimal», plutôt saisir le bytea sous forme de chaîne, avec un escaping hexadécimal. Mais oui, c'est la meilleure façon de faire, c'est l'escaping le plus performant.
Je comprend pas le:
plutôt saisir le bytea sous forme de chaîne, avec un escaping hexadécimal
je doit faire caractère par caractère et a chaque rencontre je doit faire l'échappement,?
ou un échappement en début de ligne suffi ? car j'ai vu que le bytea a en faite le même problème que le type text.
il n'y pas un moyen de mettre quelque chose sous forme brut sans ce soucier du contenu? ,j'ai l'impression de tourner en rond.
J'ai chercher des exemples de codes pour le format bytea + libpqxx = rien de valable a croire que personne a coder ce type de donnée ???
j'ai tenter les recherche avec les mots clef, "c++" bytea libqxx posgresql
google comme yahoo son muet....
Pour la conversion hexadécimal, la fonction que j'utilise en c++ ne joue pas. je cherche encore car cette fois sa semble venir de ma fonction.
Sous debian squeez, nouveaux sur le forum
Hors ligne
Avec libpq, il existe les fonctions pg_escape_text et pg_escape_bytea. Avec libpqxx, il existe escape_binary mais je n'ai pas l'impression que cela soit un vrai remplacement.
En fait, je me demande pourquoi vous passez par libpqxx. pgAdmin est codé en C++ et passe directement par la libpq.
Guillaume.
Hors ligne
En fait, quand vous écrivez
insert into ma_table (colonne) values ('mon_nom_de_fichier_pourri_avec_un_caractère_non_imprimable'), le 'mon_nom_de_fichier_pourri_avec_un_caractère_non_imprimable' est converti en interne en chaîne de caractère pour être ensuite stocké dans colonne. D'où le message d'erreur qui se produit quand même, puisqu'on a une chaîne qui n'est pas validable en unicode.
Donc oui, il faut escaper, par exemple:
insert into ma_table (colonne) values (E'\\x55657374'), pour insérer 'Test' par exemple (les valeurs ascii). => Les caractères non-imprimables s'escapent exactement de la même façon: vous mettez la (ou les, si le caractère est multibyte comme celui qui vous pose problème) valeur hexa du caractère dans la chaîne générée. Cette chaîne, dans ce format, supporte n'importe quoi en entrée, et peut être convertie en bytea.
Marc.
Hors ligne
Avec libpq, il existe les fonctions pg_escape_text et pg_escape_bytea. Avec libpqxx, il existe escape_binary mais je n'ai pas l'impression que cela soit un vrai remplacement.
En fait, je me demande pourquoi vous passez par libpqxx. pgAdmin est codé en C++ et passe directement par la libpq.
la libpq est la librairie pour le C , libpqxx est la lib destinée aux c++
Sous debian squeez, nouveaux sur le forum
Hors ligne
En fait, quand vous écrivez
insert into ma_table (colonne) values ('mon_nom_de_fichier_pourri_avec_un_caractère_non_imprimable'), le 'mon_nom_de_fichier_pourri_avec_un_caractère_non_imprimable' est converti en interne en chaîne de caractère pour être ensuite stocké dans colonne. D'où le message d'erreur qui se produit quand même, puisqu'on a une chaîne qui n'est pas validable en unicode.Donc oui, il faut escaper, par exemple:
insert into ma_table (colonne) values (E'\\x55657374'), pour insérer 'Test' par exemple (les valeurs ascii). => Les caractères non-imprimables s'escapent exactement de la même façon: vous mettez la (ou les, si le caractère est multibyte comme celui qui vous pose problème) valeur hexa du caractère dans la chaîne générée. Cette chaîne, dans ce format, supporte n'importe quoi en entrée, et peut être convertie en bytea.
Merci pour votre réponse je vais tester l'hexa, je vous dit si sa passe, pour le moment j'arrive pas a avoir ma string en hexa enfin si mai pas sur de sa valeur. mai c'est un autre sujet j'ai poster ailleur(si sa intéresse quelqu'un)
Sous debian squeez, nouveaux sur le forum
Hors ligne
Mais sinon, effectivement, gleu a raison, vous pouvez utiliser les fonctions d'escaping déjà fournies.
Marc.
Hors ligne