Tronquer les Chaînes en Octets
J'ai créer ce qui suit pour tronquer une chaîne de caractères en java pour une nouvelle chaîne avec un nombre d'octets.
String truncatedValue = "";
String currentValue = string;
int pivotIndex = (int) Math.round(((double) string.length())/2);
while(!truncatedValue.equals(currentValue)){
currentValue = string.substring(0,pivotIndex);
byte[] bytes = null;
bytes = currentValue.getBytes(encoding);
if(bytes==null){
return string;
}
int byteLength = bytes.length;
int newIndex = (int) Math.round(((double) pivotIndex)/2);
if(byteLength > maxBytesLength){
pivotIndex = newIndex;
} else if(byteLength < maxBytesLength){
pivotIndex = pivotIndex + 1;
} else {
truncatedValue = currentValue;
}
}
return truncatedValue;
C'est la première chose qui vient à mon esprit, et je sais que je pourrais faire pour l'améliorer. J'ai vu un autre post qui a été de poser une question similaire il y a, mais ils ont été tronquer les Chaînes en utilisant les octets au lieu de String.sous-chaîne. Je crois que je préfère utiliser des chaînes de caractères.sous-chaîne dans mon cas.
EDIT: j'ai juste enlevé l'UTF8 référence parce que je préfère être en mesure de le faire pour les différents types de stockage aswell.
Je voudrais reformuler votre problème. Vous êtes à essayer de s'adapter à une chaîne en un tableau d'octets qui ne peut pas être plus grand que maxUTF8BytesLength. Vous souhaitez utiliser UTF-8 pour l'encodage. Vous souhaitez copier autant de caractères que possible. - Il Correct?
bon, je dirais que c'est correct. Je tiens également à le faire de manière efficace.
J'ai juste modifié la question pour ne pas référence UTF-8. Désolé à ce sujet, il est trompeur.
bon, je dirais que c'est correct. Je tiens également à le faire de manière efficace.
J'ai juste modifié la question pour ne pas référence UTF-8. Désolé à ce sujet, il est trompeur.
OriginalL'auteur stevebot | 2010-08-26
Vous devez vous connecter pour publier un commentaire.
Pourquoi pas convertir à d'octets et de marcher en avant-obéissant UTF8 caractère de frontières, comme vous le faites, jusqu'à ce que vous avez obtenu le maximum de nombre, puis de convertir ces octets de retour dans une chaîne de caractères?
Ou vous pouvez simplement couper la chaîne d'origine si vous gardez une trace de l'endroit où la coupe doit se produire:
Note: édité pour corriger les bugs sur 2014-08-25
Pour être efficace, vous devez prendre avantage de la structure connue des données. Si vous n'avez pas à se soucier de l'efficacité et veulent une solution simple, ou vous voulez le soutien de tous les possibles Java encodage sans avoir à connaître ce que c'est, votre méthode semble assez raisonnable.
OriginalL'auteur Rex Kerr
Le plus sain solution est d'utiliser de décodeur:
OriginalL'auteur kan
Je pense que Rex Kerr solution a 2 bugs.
Veuillez trouver ma version corrigée ci-dessous:
J'ai toujours pensé que c'était loin d'être efficace. Donc, si vous n'avez pas vraiment besoin de la représentation de Chaîne de résultat et le tableau d'octets allez faire, vous pouvez utiliser ceci:
Drôle, c'est que, avec un réaliste 20-500 limite d'octets qu'ils effectuent à peu près la même SI vous créez une chaîne de caractères à partir du tableau d'octets à nouveau.
Veuillez noter que les deux méthodes supposent un utf-8 valide d'entrée qui est une hypothèse valable après l'utilisation de Java getBytes() fonction.
Je ne vois pas getBytes de jeter quoi que ce soit. Bien que docs.oracle.com/javase/7/docs/api/java/lang/..., dit "Le comportement de cette méthode lors de cette chaîne ne peut pas être codée dans le jeu de caractères est spécifié."
La page que vous avez lié montre qu'il jette UnsupportedEncodingException: "public byte[] getBytes(String charsetName) throws UnsupportedEncodingException"
Merci! Étrange, je ne sais pas quelle version j'ai utilisé lorsque j'ai posté cette solution il y a 2 ans. Mise à jour le code ci-dessus.
Au lieu de fournir le nom d'encodage comme une Chaîne de caractères, vous pouvez utiliser le jeu de caractères constantes de StandardCharsets classe parce que la Chaîne#getBytes(jeu de caractères jeu de caractères) méthode ne permet pas de jeter UnsupportedEncodingException.
OriginalL'auteur Zsolt Taskai
Utiliser l'UTF-8 CharsetEncoder et d'encoder jusqu'à la sortie ByteBuffer contient autant d'octets que vous êtes prêt à prendre, par la recherche de CoderResult.DÉPASSEMENT de capacité.
OriginalL'auteur bmargulies
Deuxième Approche ici les bonnes œuvres
http://www.jroller.com/holy/entry/truncating_utf_string_to_the
OriginalL'auteur shadow
Comme indiqué, Peter Lawrey solution a de grandes performances inconvénient (~de 3 500 msc pour 10 000 fois), Rex Kerr était beaucoup mieux (~500msc pour 10 000 fois) mais le résultat n'a pas été précis - il couper beaucoup plus que nécessaire (au lieu de rester 4000 octets qu'il reste 3500 pour quelques exemples). ci-joint, ma solution (~250msc pour 10 000 fois) en supposant que l'UTF-8 max char longueur, en octets, est de 4 (merci WikiPedia):
OriginalL'auteur Nissim Avitan
vous pouvez convertir la chaîne d'octets et de convertir ces octets en une chaîne de caractères.
il y a beaucoup de raisons pour lesquelles cela n'est pas très performant. Le principal serait la création d'un objet de la sous-chaîne() et getBytes() Cependant, vous seriez surpris de voir combien vous pouvez le faire dans une milli-seconde et qui est généralement suffisant.
Cette méthode ne gère pas les paires de substitution correctement, par exemple, substring("\uD800\uDF30\uD800\uDF30", 4).getBytes("UTF-8").la longueur sera de retour le 8, pas 4. La moitié d'une paire de substitution est représenté comme un seul octet "?" par la Chaîne.getBytes("UTF-8").
J'ai posté une variante de cette réponse ici qui doit gérer les paires de substitution correctement.
OriginalL'auteur Peter Lawrey
s = new String(s.getBytes("UTF-8"), 0, MAX_LENGTH - 2, "UTF-8");
OriginalL'auteur Ilya Lysenko
Ci-dessous en utilisant l'Expression Régulière vous pouvez aussi supprimer attaque et de fuite des blancs de l'espace des caractères à double octet.
OriginalL'auteur Gokul Limbe
C'est mon :
OriginalL'auteur Сергей Сенько
Celui-ci pourrait ne pas être la solution plus efficace, mais fonctionne
OriginalL'auteur Saúl Martínez Vidals
Je me suis amélioré sur Peter Lawrey de la solution à traiter correctement les paires de substitution. En outre, j'ai optimisé basé sur le fait que le nombre maximal d'octets par
char
dans l'encodage UTF-8 est 3.OriginalL'auteur Hans Brende