Pode-se usar uma String para representar o corpo de uma resposta HTTP e usar o tamanho para definir o cabeçalho "Content-Length", especificado em octetos / bytes, não em caracteres. w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
iX3
4
Uma coluna do banco de dados pode ter restrição de comprimento em bytes, por exemplo, VARCHAR2 (4000 BYTE) no Oracle. Pode-se querer saber a contagem de bytes de uma String na codificação desejada para saber se a String seria adequada.
Somu
@ iX3 Exatamente o mesmo que eu estava tentando fazer.
MC Emperor
1
Acredito que existem duas interpretações possíveis para essa pergunta, dependendo da intenção: uma é "quanta memória minha String usa?". A resposta é fornecida por @roozbeh abaixo (talvez sutilezas do módulo VM como OOPS compactado). A outra é "se eu converter a string em um byte [] quanta memória essa matriz de bytes usaria?". Esta é a pergunta que é respondida por Andrzej Doyle. A diferença pode ser grande: "Hello World" em UTF8 é de 11 bytes, mas a String (por @roozbeh) é de 50 bytes (se minha matemática estiver correta).
Blanc L.
Eu deveria ter acrescentado que os 11 bytes não incluem a sobrecarga do objeto byte [] que os contém, portanto a comparação é um pouco enganadora.
L. Blanc
Respostas:
289
Uma string é uma lista de caracteres (ou seja, pontos de código). O número de bytes utilizados para representar a sequência depende inteiramente da codificação usada para transformá-la em bytes .
Dito isso, você pode transformar a string em uma matriz de bytes e, em seguida, analisar seu tamanho da seguinte maneira:
// The input string for this testfinalString string ="Hello World";// Check length, in charactersSystem.out.println(string.length());// prints "11"// Check encoded sizesfinalbyte[] utf8Bytes = string.getBytes("UTF-8");System.out.println(utf8Bytes.length);// prints "11"finalbyte[] utf16Bytes= string.getBytes("UTF-16");System.out.println(utf16Bytes.length);// prints "24"finalbyte[] utf32Bytes = string.getBytes("UTF-32");System.out.println(utf32Bytes.length);// prints "44"finalbyte[] isoBytes = string.getBytes("ISO-8859-1");System.out.println(isoBytes.length);// prints "11"finalbyte[] winBytes = string.getBytes("CP1252");System.out.println(winBytes.length);// prints "11"
Veja bem, mesmo uma simples string "ASCII" pode ter um número diferente de bytes em sua representação, dependendo da codificação usada. Use o conjunto de caracteres de seu interesse para o seu caso, como argumento getBytes(). E não caia na armadilha de supor que UTF-8 represente todos os caracteres como um único byte, pois isso também não é verdade:
finalString interesting ="\uF93D\uF936\uF949\uF942";// Chinese ideograms// Check length, in charactersSystem.out.println(interesting.length());// prints "4"// Check encoded sizesfinalbyte[] utf8Bytes = interesting.getBytes("UTF-8");System.out.println(utf8Bytes.length);// prints "12"finalbyte[] utf16Bytes= interesting.getBytes("UTF-16");System.out.println(utf16Bytes.length);// prints "10"finalbyte[] utf32Bytes = interesting.getBytes("UTF-32");System.out.println(utf32Bytes.length);// prints "16"finalbyte[] isoBytes = interesting.getBytes("ISO-8859-1");System.out.println(isoBytes.length);// prints "4" (probably encoded "????")finalbyte[] winBytes = interesting.getBytes("CP1252");System.out.println(winBytes.length);// prints "4" (probably encoded "????")
(Observe que, se você não fornecer um argumento para o conjunto de caracteres, o conjunto de caracteres padrão da plataforma será usado. Isso pode ser útil em alguns contextos, mas, em geral, você deve evitar os padrões e sempre usar um conjunto explícito de caracteres ao codificar / decodificação.)
. por isso novamente se eu usar getBytes () ele vai me dar o comprimento igual x.length estou errado eu, porque eu não tenho certeza
Verde
4
@ Green Ash O comprimento da matriz de bytes - getBytes () - e x.length PODE ser igual, mas não é garantido que seja. Será igual se todos os caracteres forem representados por um único byte cada. Isso sempre será verdadeiro para codificações de caracteres que usam um único byte por caractere (ou menos), como ISO-8859-1. O UTF-8 usa 1 ou 2 bytes, portanto depende dos caracteres exatos na sequência. Depois, há codificações de caracteres que sempre usam dois bytes por caractere.
Kris
eu gosto da sua resposta :), então eles podem ser de alguma forma iguais, mas nem sempre eu estou certo? ok então é ok usar o método sem o parâmetro porque está me causando um erro !!
Verde
@ O ponto verde é que o número de bytes nem sempre é igual ao número de caracteres . O número de bytes depende da codificação de caracteres usada. Você precisará saber qual codificação de caracteres usará e levar isso em conta. que erro você está tendo? Se você apenas o usar getBytes(), usará a codificação de caracteres padrão do seu sistema.
Jesper
1
@KorayTugay Sim, mais ou menos. Você pode discutir sobre a ordem de causa e efeito, no entanto. Eu estaria mais inclinado a afirmar que um caractere sempre tem 2 bytes, porque é um tipo de dados primitivo definido para ter 2 bytes de largura. (E que a representação UTF-16 era principalmente uma consequência deste, ao invés do contrário.)
Andrzej Doyle
63
Se você estiver executando com referências de 64 bits:
sizeof(string)=8+// object header used by the VM8+// 64-bit reference to char array (value)8+ string.length()*2+// character array itself (object header + 16-bit chars)4+// offset integer4+// count integer4+// cached hash code
Em outras palavras:
sizeof(string)=36+ string.length()*2
Em uma VM de 32 bits ou de 64 bits com OOPs compactados (-XX: + UseCompressedOops), as referências são de 4 bytes. Portanto, o total seria:
sizeof(string)=32+ string.length()*2
Isso não leva em consideração as referências ao objeto string.
Eu estava assumindo que a pergunta era sobre o número de bytes alocados na memória para um objeto String. Se a pergunta é sobre o número de bytes necessários para serializar a String, como outros indicaram, isso depende da codificação usada.
Roozbeh
2
Fonte para sua resposta? Graças
Luna
1
Nota: sizeofdeve ser múltiplo de 8.
dieter
19
A resposta pedante (embora não necessariamente a mais útil, dependendo do que você quer fazer com o resultado) é:
string.length()*2
As seqüências Java são fisicamente armazenadas na UTF-16BEcodificação, que usa 2 bytes por unidade de código e String.length()mede o comprimento em unidades de código UTF-16, portanto, isso é equivalente a:
E isso informará o tamanho da charmatriz interna , em bytes .
Nota: "UTF-16"fornecerá um resultado diferente, "UTF-16BE"pois a codificação anterior inserirá uma lista técnica , adicionando 2 bytes ao comprimento da matriz.
A resposta de Roozbeh é melhor, porque leva em consideração os outros bytes também.
Lodewijk Bogaards 30/03/19
@finnw Tem certeza de que a codificação é UTF-16BE e não UTF-16? De acordo com a classe String Javadoc ( docs.oracle.com/javase/6/docs/api/java/lang/String.html ), "Uma String representa uma string no formato UTF-16 ...".
mas desculpe-me quando compilo seu código, isso me dá um erro; por causa do parâmetro "UTF-8" .where, quando passo um parâmetro vazio, me dá o mesmo comprimento que x.length. Eu entendi mal o conceito. ajuda por favor
Green
@ Green Ash, qual versão do Java você possui?
Buhake Sindi
@ Green Ash, que exceção você está recebendo?
Buhake Sindi
2
para ficar claro, esta é a saída: test.java:11: exceção não relatada java.io.UnsupportedEncodingException; deve ser capturado ou declarado como acionado byte [] b = s.getBytes ("UTF-8"); ^ 1 erro Processo concluído.
Uma Stringinstância aloca uma certa quantidade de bytes na memória. Talvez você esteja olhando para algo comosizeof("Hello World") que retornaria o número de bytes alocados pela própria estrutura de dados?
Em Java, geralmente não há necessidade de uma sizeoffunção, porque nunca alocamos memória para armazenar uma estrutura de dados. Podemos dar uma olhada no String.javaarquivo para obter uma estimativa aproximada, e vemos alguns 'int', algumas referências e a char[]. A especificação da linguagem Java define, que charvaria de 0 a 65535, portanto, dois bytes são suficientes para manter um único caractere na memória. Mas uma JVM não precisa armazenar um caractere em 2 bytes, apenas tem que garantir que a implementação dechar possa conter valores do intervalo define.
Então, sizeofrealmente não faz sentido em Java. Mas, supondo que tenhamos uma String grande e uma charaloque dois bytes, o espaço ocupado pela memória de um Stringobjeto será pelo menos 2 * str.length()em bytes.
Sabiamente = não use aquele sem um parâmetro de conjunto de caracteres.
Thilo
Por quê? Isso é um problema se eu configurar meu ambiente para executar com a codificação UTF8?
Ziggy
1
O getBytes também criará e copiará a matriz de bytes; portanto, se você estiver falando de cadeias longas, essa operação poderá ficar cara.
ticktock
@ticktock, se você ainda está por perto, sim, mas qual é a alternativa? Cheguei aqui esperando que uma função de biblioteca retornasse o armazenamento necessário para que eu pudesse combiná-lo em uma alocação maior.
Respostas:
Uma string é uma lista de caracteres (ou seja, pontos de código). O número de bytes utilizados para representar a sequência depende inteiramente da codificação usada para transformá-la em bytes .
Dito isso, você pode transformar a string em uma matriz de bytes e, em seguida, analisar seu tamanho da seguinte maneira:
Veja bem, mesmo uma simples string "ASCII" pode ter um número diferente de bytes em sua representação, dependendo da codificação usada. Use o conjunto de caracteres de seu interesse para o seu caso, como argumento
getBytes()
. E não caia na armadilha de supor que UTF-8 represente todos os caracteres como um único byte, pois isso também não é verdade:(Observe que, se você não fornecer um argumento para o conjunto de caracteres, o conjunto de caracteres padrão da plataforma será usado. Isso pode ser útil em alguns contextos, mas, em geral, você deve evitar os padrões e sempre usar um conjunto explícito de caracteres ao codificar / decodificação.)
fonte
getBytes()
, usará a codificação de caracteres padrão do seu sistema.Se você estiver executando com referências de 64 bits:
Em outras palavras:
Em uma VM de 32 bits ou de 64 bits com OOPs compactados (-XX: + UseCompressedOops), as referências são de 4 bytes. Portanto, o total seria:
Isso não leva em consideração as referências ao objeto string.
fonte
sizeof
deve ser múltiplo de 8.A resposta pedante (embora não necessariamente a mais útil, dependendo do que você quer fazer com o resultado) é:
As seqüências Java são fisicamente armazenadas na
UTF-16BE
codificação, que usa 2 bytes por unidade de código eString.length()
mede o comprimento em unidades de código UTF-16, portanto, isso é equivalente a:E isso informará o tamanho da
char
matriz interna , em bytes .Nota:
"UTF-16"
fornecerá um resultado diferente,"UTF-16BE"
pois a codificação anterior inserirá uma lista técnica , adicionando 2 bytes ao comprimento da matriz.fonte
De acordo com Como converter seqüências de caracteres para e de matrizes de bytes UTF8 em Java :
fonte
s.getBytes(Charset.forName("UTF-8"))
.Uma
String
instância aloca uma certa quantidade de bytes na memória. Talvez você esteja olhando para algo comosizeof("Hello World")
que retornaria o número de bytes alocados pela própria estrutura de dados?Em Java, geralmente não há necessidade de uma
sizeof
função, porque nunca alocamos memória para armazenar uma estrutura de dados. Podemos dar uma olhada noString.java
arquivo para obter uma estimativa aproximada, e vemos alguns 'int', algumas referências e achar[]
. A especificação da linguagem Java define, quechar
varia de 0 a 65535, portanto, dois bytes são suficientes para manter um único caractere na memória. Mas uma JVM não precisa armazenar um caractere em 2 bytes, apenas tem que garantir que a implementação dechar
possa conter valores do intervalo define.Então,
sizeof
realmente não faz sentido em Java. Mas, supondo que tenhamos uma String grande e umachar
aloque dois bytes, o espaço ocupado pela memória de umString
objeto será pelo menos2 * str.length()
em bytes.fonte
Existe um método chamado getBytes () . Use com sabedoria.
fonte
Tente o seguinte:
Supondo que você declarou e inicializou x antes
fonte
Bytes
turma.Para evitar tentar capturar, use:
fonte