PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 06/03/2012 03:12:55

Sub
Membre

séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#2 06/03/2012 09:53:03

gleu
Administrateur

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#3 06/03/2012 10:08:19

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#4 06/03/2012 13:47:38

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

gleu a écrit :

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

#5 06/03/2012 13:51:17

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Marc Cousin a écrit :

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

#6 06/03/2012 15:07:45

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#7 06/03/2012 16:31:30

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Marc Cousin a écrit :

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

#8 06/03/2012 16:36:59

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#9 06/03/2012 19:52:10

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Marc Cousin a écrit :

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

#10 07/03/2012 10:45:27

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#11 07/03/2012 12:37:22

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Marc Cousin a écrit :

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

#12 07/03/2012 12:49:34

gleu
Administrateur

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#13 07/03/2012 12:55:28

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

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

#14 07/03/2012 14:04:29

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

gleu a écrit :

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

#15 07/03/2012 14:09:31

Sub
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Marc Cousin a écrit :

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)

http://www.debian-fr.org/c-std-string-e … 37868.html


Sous debian squeez, nouveaux sur le forum

Hors ligne

#16 07/03/2012 15:32:20

Marc Cousin
Membre

Re : séquence d'octets invalide pour l'encodage « UTF8 » : 0xf1616e61

Mais sinon, effectivement, gleu a raison, vous pouvez utiliser les fonctions d'escaping déjà fournies.


Marc.

Hors ligne

Pied de page des forums