9
votes

Est-il possible d'ajouter des données à une chaîne après avoir ajouté "\ 0" (null)?

J'ai une chaîne que je crée, et je dois ajouter plusieurs caractères "\ 0" (null) à la chaîne. Entre chaque caractère NULL, est d'autres données de texte (uniquement des caractères alphanumériques ASCII).

Mon problème est que dans J2SE lorsque vous ajoutez la première null (\ 0), Java semble alors déterminer qu'il s'agit d'un terminateur à chaîne (similaire à C ++) et ignore toutes les autres données en annexe. Aucune erreur n'est soulevée, les données de fin sont simplement ignorées. J'ai besoin de forcer les données de fuite supplémentaires après une nulle dans la chaîne. Je dois le faire pour une base de données héritée que je supporte.

J'ai essayé de coder / décoder la chaîne dans l'espoir que quelque chose comme% 00 tromperait l'interprétation du comportement de la chaîne, mais quand je suis -L'engager la chaîne, Java voit à nouveau le caractère NULL et supprime toutes les données après la première null.

mise à jour: Voici l'extrait de code correspondant. Oui, j'essaie d'utiliser strings . J'ai l'intention d'essayer des caractères, mais je dois toujours l'enregistrer dans la base de données comme une chaîne, je suppose donc que je finirai avec le même problème.

de fond. Je reçois des données via http post qui a "\ n". Je dois supprimer les nouvelles lignes et les remplacer par "\ 0". La méthode " débogage " est juste une méthode simple qui fait system.out.println . xxx

snewvalue, a String, est engagée dans la base de données et doit être effectuée sous forme de chaîne. Ce que je suis observé lorsque j'affiche la valeur actuelle de snewvalue après que chaque itération de la console est quelque chose comme ceci:

entrée est la valeur1 \ nvalue2 \ nvalue3 La sortie dans la console me donne de ce code xxx

Je m'attends xxx

avec null non imprimable entre valeur1 , valeur2 et valeur3 respectivement. Notez que la valeur réellement enregistrée dans la base de données est également simplement "valeur1". Donc, ce n'est pas simplement un problème d'affichage de la console. Les données après \ 0 sont ignorées.


9 commentaires

En Java, vous ne pouvez jamais dire "caractère null". C'est un null la valeur et Java n'utilise pas les caractères ASCII plutôt qu'il utilise Unicode.


Qu'avez-vous l'intention de faire avec cette chaîne une fois que vous l'avez?


@Lion: Untrue - Caractère 0 dans Unicode est connu sous le nom de caractère null. Voir Unicode.org/charts/pdf/u0000.pdf


@Jon Skeet :) Merci pour cette information. Appris quelque chose de nouveau.


(Et c'est pourquoi je préfère appeler cela le personnage "Nul", bien que Il est également connu sous le nom de " null "caractère )


J'ai mis à jour la question avec le code ..


@giulio: Donc, peut-être peut-être system.out.println le tronque - ou plutôt, tout ce qui est en train d'imprimer (par exemple une IDE). Cela ne signifie pas que les données ne sont pas là ...


@Jonskeet je pensais que ça. J'ai vérifié ce qui a été écrit à la base de données et c'est cohérent avec la console. Je n'utilise pas la JVM de Sun. Je pense que c'est ça le problème. Voir mon commentaire dans votre réponse. thnx


@giulio: Juste regarder le DB ne suffit pas pour diagnostiquer ce qui se passe. Vous devez regarder la longueur de la chaîne, imprimer la valeur Unicode de chaque caractère, etc.


4 Réponses :


2
votes

Je vous suggère d'utiliser un char [] ou list car il semble que vous n'utilisez pas vraiment une chaîne En tant que telle (une vraie chaîne ne contient normalement pas de nulles ou d'autres caractères non dérivés).


9 commentaires

-1: une "chaîne réelle" peut contenir des caractères nuls sans problèmes. C'est juste un autre personnage en ce qui concerne Java.


@Jon techniquement oui, mais ce n'est pas une bonne idée


Pourquoi pas? Si l'OP veut représenter une telle chaîne pour une raison valable, et il n'y a pas de raison technique, cela ne devrait pas fonctionner, pourquoi l'éviter? Cela ressemble à un problème d'affichage plus que toute autre chose.


Ce n'est pas vraiment une séquence de personnages. Il est (AB) en utilisant string pour contenir une séquence délimitée. Il devrait probablement créer sa propre classe wrapper.


Oui, c'est est une séquence de caractères - tout simplement des caractères imprimables. Mettez-le de cette façon: s'il s'agissait d'une séquence de virgule virgule , vous ne clignes pas, non? Alors, quelle est la grosse affaire sur l'utilisation du caractère u + 0000 u + 0000 parfaitement valide que le séparateur?


@Jon je voudrais utiliser une virgule si je devais l'écrire dans un fichier d'échange de données; Mais je suppose que ce code est destiné à une API héritée qui lit des ruisseaux d'octets séparés nuls. Le reste de l'application doit être blindé à partir de ceci (à l'aide d'une liste ou quelque chose de similaire), et la partie de l'application qui interface devrait probablement utiliser une sortie . . Je suppose également que l'application se briserait s'il utilisait un codage qui mappait le caractère null à autre chose qu'un octet unique avec la valeur 0x00.


Le reste de l'application devrait presque certainement utiliser une liste pour stocker une collection de chaînes et je ne vois aucune indication que ce n'est pas le cas de la question. Je ne vois pas comment Char [] est meilleur ici ... C'est plus une collection de chaînes avec un délimiteur que d'une gamme de personnages, n'est-ce pas?


Je dois utiliser JDK 1.4.2 (Cringe). Les génériques ne sont pas pris en charge.


@giulio: Ensuite, juste Liste - La partie générique est juste une netteté vraiment. Vous ne devez utiliser que la partie de chaîne concaténée où vous devez - en interne, vous devez conserver des collections comme collections.



1
votes

Même comportement pour le Stringbuffer Classe?

depuis "\ 0" fait des problèmes, je recommanderais de ne pas l'utiliser. J'essaierais de remplacer un meilleur délimiteur avec "\ 0" lors de l'écriture de la chaîne à votre dB.


0 commentaires

0
votes

Ceci est parce que \ code> est un caractère d'échappement dans Java (comme dans de nombreuses langues associées à C) et vous devez vous échapper à l'aide d'un supplémentaire code> comme suit.

String str="\\0Java language";
System.out.println(str);


2 commentaires

'\' n'est pas une expression régulière. C'est juste un personnage d'échappement dans les littéraux à cordes.


L'op ne veut pas la barre oblique inverse, suivie d'un zéro dans la corde - il veut le caractère Null Unicode, U + 0000.



15
votes

I Suspect em> soupçonne que ce n'est rien à voir avec le texte de la chaîne elle-même - je soupçonne que c'est juste comment il est affiché. Par exemple, essayez ceci:

for (int i = 0; i < text.length(); i++) {
    System.out.println((int) text.charAt(i));
}


11 commentaires

De même, si vous l'écrivez à la base de données avec Paretstatement.Setstring (), je ne sais pas quelle sera la base de données. Peut-être que c'est plus sûr avec des sertissements () ou SetBlob ().


@greyfaire: non si le type de champ de la base de données est varchar ou quelque chose de similaire, imo.


Le cœur du problème semble être le comportement de la classe de cordes et ce qu'il fait quand il voit "\ 0".


@giulio Avez-vous essayé de déboguer (Svalue.length ())? Vous verrez, ce n'est pas un problème de chaîne.


@giulio: Je n'ai vu aucune preuve pour cela et montré un programme court mais complet montrant qui semble démontrer le contraire. Pouvez-vous créer un programme similaire court mais complet que fait démontre le problème?


@giulio string ne traite pas Treat \ 0 comme un caractère spécial. Vous pouvez avoir n'importe quel numéro \ 0 caractères dans une chaîne. Cependant, j'ai vu des bases de données et des outils d'interface graphique écrits dans des chaînes tronquées avec un \ 0.


@Jonskeet. J'ai écrit une petite application Java rapide et vous êtes correct. Le \ 0 est affiché dans la sortie, en tant que caractère non imprimable, mais il affiche comme prévu. Je dois utiliser JVM de IBM . Je commence à penser que c'est la JVM d'IBM. Comme j'ai toujours le même problème dans la JVM d'IBM. Je me penche vers l'idée que c'est la merde Jvm de IBM et son traitement des cordes. Soupir!


@giulio: même dans l'IBM JVM, je fortement doute que le comportement de string va varier comme ça. Avez-vous essayé le court exemple dans ma réponse dans l'IBM JVM? Quelle longueur est-elle imprimée? Comme je l'ai déjà dit, je suis presque certain que le problème est dans ce que vous affichez, pas les données de la chaîne elle-même.


@Jonskeet J'apprécie que j'ai vérifié la cible de la DB, et cela ne semble pas être un problème d'affichage de la console. Vous m'avez embrouillé de continuer à tester mon code. J'ai fait assez d'erreurs au fil des ans pour toujours suspecter que c'est moi, mais celui-ci est assez étrange.


@giulio: Vérification de la console et la DB est une mauvaise façon de diagnostiquer le problème, car tant de choses peuvent interférer entre vos données et ces sorties de débogage. Consultez mon édition au bas de la réponse pour une façon de voir le contenu de la chaîne avec précision. Je pense que vous pouvez compter sur system.out.println travail pour les entiers :)


@Jonskeet J'ai vérifié la valeur ASCII dans la chaîne que j'essaie de sauvegarder et je reçois toutes les valeurs de là comme éteint, mais la manière dont l'IBM JVM TreatS \ 0 est différent du JVM de Sun car il ne s'affiche pas La console sous la machine virtuelle IBM, mais s'affichera comme un caractère non imprimable à Sun's JVM. Je pense aussi maintenant que la base de données tronque la valeur quand elle voit \ 0. Je pense que c'est la fin de la route sur ce problème, car vous avez démontré comment tester ce qui se passe. Avec votre aide, j'ai confirmé que cela est possible avec JVM de Sun, il n'est tout simplement pas possible avec IBM. +1. Thnx