contar caracteres  XML
Índice dos Fóruns » Interface Gráfica
Autor Mensagem
franchico
Entusiasta Java

Membro desde: 11/10/2007 13:14:48
Mensagens: 23
Offline

Bom dia Pessoal.

estou com o seguinte código, para contar o numero de caracteres de um arquivo, no entanto ele não está contando todos, ao meu ver os espaços e alguns outros caracteres que não sejam letras ele não conta.
no meu ex. o arquivo tem 270 bytes, o codigo tá me dizendo que são 206.
podem me ajudar?

import java.io.BufferedReader;

public class ContadorDeCaracteres {
public static void main(String args[]) throws Exception {
BufferedReader arquivo = new BufferedReader(new java.io.FileReader("D:\\SystemCheckOut.txt"));
String linha=null;
int Caracteres = 0;
while (arquivo.ready()) {
try{
linha=arquivo.readLine();
Caracteres += linha.length();
}catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("numero de caracteres "+Caracteres);
}
}

Atenciosamente.

"voce é responsável por todos os seus atos, e por todo o seu estado de espirito"
LuizClaudio
JavaEvangelist
[Avatar]

Membro desde: 03/04/2006 21:50:51
Mensagens: 388
Offline

readLine

public String readLine()
throws IOException

Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.



Ou seja, acho que vc tem de adicionar um caracter a cada linha!

"Porque Deus amou o mundo de tal maneira que deu seu filho unigênito para que todo aquele que nele crê não pereça, mas tenha vida eterna." João 3.16
[WWW]
celso.martins
Virtual Machine Man
[Avatar]

Membro desde: 19/06/2006 13:54:23
Mensagens: 699
Localização: Rio de Janeiro
Offline

franchico wrote:Bom dia Pessoal.

estou com o seguinte código, para contar o numero de caracteres de um arquivo, no entanto ele não está contando todos, ao meu ver os espaços e alguns outros caracteres que não sejam letras ele não conta.
no meu ex. o arquivo tem 270 bytes, o codigo tá me dizendo que são 206.
podem me ajudar?

import java.io.BufferedReader;

public class ContadorDeCaracteres {
public static void main(String args[]) throws Exception {
BufferedReader arquivo = new BufferedReader(new java.io.FileReader("D:\\SystemCheckOut.txt"));
String linha=null;
int Caracteres = 0;
while (arquivo.ready()) {
try{
linha=arquivo.readLine();
Caracteres += linha.length();
}catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("numero de caracteres "+Caracteres);
}
}

Atenciosamente.


Amigo, esses 270 pode ser devido ao tamanho do cluster do disco rígido. Por exemplo, se o SO precisa armazenar uma palavra de 8 bytes em um cluster de 64 bytes, o SO usará todos os 64 bytes do cluster para essa palavra. Pode reparar que se você colocar esse mesmo arquivo numa pen-drive ele ficará com tamanho diferente. Não sei se você está levando em consideração isso. Caso já esteja, desconsidere a minha mensagem.

Se não estiver levando em consideração, dá uma procurada em Arquitetura de Computadores - Armazenamento, para maiores (e melhores) esclarecimentos.

Outra opção, para acabar definitivamente com as dúvidas, seria usar uma forma de mais baixo nível para ler o arquivo. Uso isso para ler uns anexos meio doido que recebo, de informação de GPS. O IF é maior (tem vários else), mas acho que esse dá para exemplificar:



Esse código tem uns 150 anos mais ou menos, e nunca foi refatorado. Está lá jogado numa pasta num CD numa gaveta em uma prateleira.

Hoje melhor que ontem e pior que amanhã.

Desenvolvimento Psicopata - Qualidade Total
Twitter
Infoblogs - A vitrine do seu blog
[Email] [WWW]
franchico
Entusiasta Java

Membro desde: 11/10/2007 13:14:48
Mensagens: 23
Offline

parece que não é só isso, mas de qualquer forma valeu

"voce é responsável por todos os seus atos, e por todo o seu estado de espirito"
franchico
Entusiasta Java

Membro desde: 11/10/2007 13:14:48
Mensagens: 23
Offline

a resposta anterior fui para o luis.
Claudio, obrigado vou analisar sua instrução.
obrigado.

"voce é responsável por todos os seus atos, e por todo o seu estado de espirito"
LuizClaudio
JavaEvangelist
[Avatar]

Membro desde: 03/04/2006 21:50:51
Mensagens: 388
Offline

Desculpe, mas agora fiquei confuso, vc tá catando o número de byte, através do caracters??? Pq vc num faz simplismente isso?

This message was edited 1 time. Last update was at 08/11/2007 11:31:57


"Porque Deus amou o mundo de tal maneira que deu seu filho unigênito para que todo aquele que nele crê não pereça, mas tenha vida eterna." João 3.16
[WWW]
franchico
Entusiasta Java

Membro desde: 11/10/2007 13:14:48
Mensagens: 23
Offline

Luiz,

Deixe-me explicar melhor, talvez eu esteja confuso.
Eu preciso comparar a quantidade de caracteres de dois arquivos, então eu to pensando assim:
Eu descubro quantos caracteres tenho em um, depois vejo quantos tem no outro e... futuramente, vejo se os dois teem os mesmos caracteres, talvez a lógica que estou usando esteja errada. Será que existe uma forma mais fácil, ou é assim mesmo?
Valeu,

"voce é responsável por todos os seus atos, e por todo o seu estado de espirito"
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

O tempo passa, as linguagens evoluem. Saímos das linguagens baseadas em caracteres Ascii e agora entramos na era Unicode. Entretanto, algumas pessoas ainda tratam strings como os velhos caracteres de 7 bits do passado.

No mundo Unicode, o quão longa é uma String?

Você pode estar tentando a dizer: Fácil, simplesmente use o método length() para isso. Geralmente, a resposta estará correta, mas esse não é o único meio, e também nem sempre é o meio correto. Na verdade, existem três maneiras de se obter o tamanho de uma String:

Você pode obter o número de unidades de char;
Você pode obter o número de caracteres ou code points;
Você pode obter o número de bytes.

Contando o unidades de char

O java usa o padrão Unicode para definir seus caracteres. A definição inicial do unicode era de caracteres de tamanho fixo, com 16 bits, entre U+0000 até U+FFFF - o símbolo U+ significa um caracter válido Unicode, representado em seguida pro seu código hexadecimal. Convenientemente e não por acaso, o java adotou uma largura fixa de dois bytes para o tipo char. Assim, um char representa qualquer caracter de 16 bits.

A maior parte dos programadores é familiar com o metodo length. O código a seguir conta o número de caracteres numa string de exemplo. Note que essa String possui uma série de caracteres simples e alguns definidos com a notação \u. A notação \u é a equivalente em Java ao padrão unicode U+, e é usada para definir um caracter unicode de 16 bits através de sua notação hexadecimal.


O método Length conta o número de caracteres na String.
O código de exemplo imprime: caracteres: 7

Contando unidades de caracteres (ou code points)
Entretanto, anos mais tarde o padrão Unicode 4.0 definiu um número significativamente maior do que U+FFFF. Isso fez com que o Java passasse a ser incapaz de de representar todos os caracteres. A solução para esse problema surgiu a partir do Java 5, quando pares de chars de 16 bits passaram a ser utilizados para representar um caracter unicode. Esses pares passaram a ser conhecidos como pares substitutos (surrogate pairs).

Apesar de um char ainda poder representar um caracter unicode até U+FFFF, apenas um par pode representar caracteres suplementares. Os valores suplementares possuem o valor mais alto do par no intervalo entre U+DC00 até U+DFFF. O padrão também define um algoritmo para mapear entre um par substituto e um caracter acima de U+FFFF. Com esses pares é possível representar qualquer caracter no padrão Unicode. Mas isso também significa que um caracter de bits pode ser uma unidade de código que não representa um caracter completo unicode (code point).

O método length() não conta os caracteres suplementares, pois ele apenas conta unidades char, sem se preocupar com que eles significam. Os programadores do Java 5 forneceram então um novo método, chamado codePointCount(int beginIndex, int endIndex) capaz de lidar com essa tarefa. Esse método informa quantos caracteres Unicode estão entre os dois indices. Os índices referem-se a unidades de char, como no método length().

Dessa forma, se você subtrair endIndex - begin index para a totalidade de uma String, obterá o mesmo valor que o método length(). Entretanto, esse valor poderá ser completamente diferente do valor de retorno do método codePointCount. Se o seu texto contiver pares substitutos, o tamanho retornado por length() e pelo método codePointCount certamente será diferente. Um surrogate pair define um único code point, mas pode ser definido por uma ou duas unidades de caracteres.

Vejamos um exemplo:



Esse exemplo imprime:
Número de caracteres: 6

A variável testString contém dois caracteres interessantes, que são os ideogramas japoneses significando ?aprendizado? e um caracter chamado GOTHIC LETTER AHSA. A letra japonesa tem o valor unicode U+5B66, que pode ser representada por apenas um caracter unicode. Entretanto, a letra gótica tem o valor representado pelo par \uD800\uDF30. Como esse par representa apenas um caracter unicode, o valor total de caracteres na String é 6, e não 7.

Contando o número de Bytes
Quantos bytes tem uma String? A resposta varia de acordo com o charset utilizado. A razão para que isso seja perguntado, geralmente é satisfazer o tamanho de um campo num banco de dados. O método getBytes() converte os caracteres Unicode em uma representação orientada a bytes, retornando um byte[]. Uma codificação orientada a bytes é a UTF8, que é diferente de todas as representações unicode pois pode representar de maneira adequada qualquer code point Unicode.

O código abaixo converte o texto num array de bytes:


System.out.printf("Número de bytes em UTF-8: %dn", byteCount);O charset destino ( UTF8 ) é quem define quantos bytes serão gerados. O UTF8 transforma um code point unicode em uma até quadro unidades de código de 8 bits (um byte). Assim, os caracteres a, b, c e d juntos requerem apenas um total de quatro bytes. O caracter japonês passa a representar 3 bytes. Finalmente a letra Gótica representa quatro bytes. O resultado total exibido é esse:

Número de bytes em UTF8 Byte: 11

Em resumo
A menos que você utilize caracteres suplementares, você nunca verá diferença entre os valores de retorno de length e codePointCount. Entretanto, caso você queira enviar seus produtos para a crescente China ou para o Japão, você certamente se deparará com esse tipo de caracter, e ficará muito satisfeito por saber que esse método existe.

Transmissões de rede, ou gravações em bancos de dados, recomendam o formato UTF8. Nesse caso, mais uma vez o tamanho da String irá variar enormemente.

Vários métodos para avaliar o tamanho foram apresentados, agora, cabe a você analisar qual é a opção correta para medir sua String.

This message was edited 5 times. Last update was at 18/06/2008 07:35:10


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
LuizClaudio
JavaEvangelist
[Avatar]

Membro desde: 03/04/2006 21:50:51
Mensagens: 388
Offline

franchico wrote:Luiz,

Deixe-me explicar melhor, talvez eu esteja confuso.
Eu preciso comparar a quantidade de caracteres de dois arquivos, então eu to pensando assim:
Eu descubro quantos caracteres tenho em um, depois vejo quantos tem no outro e... futuramente, vejo se os dois teem os mesmos caracteres, talvez a lógica que estou usando esteja errada. Será que existe uma forma mais fácil, ou é assim mesmo?
Valeu,



pelo que eu entendi, vc ta querendo a quantidade pra evitar ter de comparar caracter por caracter de todos arquivos, eu faria com o método hashCode() da classe String, a idéia é que se o hashCode da String do conteúdo é igual então o conteúdo é igual, e vc só guarda o hashCode para comparar num prescisa ficar comparando o conteúdo diretamente.

Como todo programador é muito vaidoso, antes que vc fique puto pq eu tô me metendo da sua lógica, não sou dono da verdade, sou só um cara tentando te ajudar!

"Porque Deus amou o mundo de tal maneira que deu seu filho unigênito para que todo aquele que nele crê não pereça, mas tenha vida eterna." João 3.16
[WWW]
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

LuizClaudio wrote:
pelo que eu entendi, vc ta querendo a quantidade pra evitar ter de comparar caracter por caracter de todos arquivos, eu faria com o método hashCode() da classe String, a idéia é que se o hashCode da String do conteúdo é igual então o conteúdo é igual, e vc só guarda o hashCode para comparar num prescisa ficar comparando o conteúdo diretamente.


Ainda sim, tem que tomar cuidado. Hashcodes iguais podem ser gerados para strings de valores diferentes. O Thingol postou a um tempo atrás aqui alguns exemplos.

@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
LuizClaudio
JavaEvangelist
[Avatar]

Membro desde: 03/04/2006 21:50:51
Mensagens: 388
Offline

ViniGodoy wrote:
LuizClaudio wrote:
pelo que eu entendi, vc ta querendo a quantidade pra evitar ter de comparar caracter por caracter de todos arquivos, eu faria com o método hashCode() da classe String, a idéia é que se o hashCode da String do conteúdo é igual então o conteúdo é igual, e vc só guarda o hashCode para comparar num prescisa ficar comparando o conteúdo diretamente.


Ainda sim, tem que tomar cuidado. Hashcodes iguais podem ser gerados para strings de valores diferentes. O Thingol postou a um tempo atrás aqui alguns exemplos.



ViniGodoy vc lembra qual era o título do post?

franchico, então se o Hashcode for igual vc compara o conteúdo, mesmo assim ainda melhor do que contar os caracteres, pelo menos eu acho?



"Porque Deus amou o mundo de tal maneira que deu seu filho unigênito para que todo aquele que nele crê não pereça, mas tenha vida eterna." João 3.16
[WWW]
celso.martins
Virtual Machine Man
[Avatar]

Membro desde: 19/06/2006 13:54:23
Mensagens: 699
Localização: Rio de Janeiro
Offline

ViniGodoy wrote:
LuizClaudio wrote:
pelo que eu entendi, vc ta querendo a quantidade pra evitar ter de comparar caracter por caracter de todos arquivos, eu faria com o método hashCode() da classe String, a idéia é que se o hashCode da String do conteúdo é igual então o conteúdo é igual, e vc só guarda o hashCode para comparar num prescisa ficar comparando o conteúdo diretamente.


Ainda sim, tem que tomar cuidado. Hashcodes iguais podem ser gerados para strings de valores diferentes. O Thingol postou a um tempo atrás aqui alguns exemplos.


Vini, aquela solução com while que eu passei, não contaria os caracteres do arquivo, independentemente de qualquer variação, mencionada naquela sua ótima explicação, mensagens atrás?

Hoje melhor que ontem e pior que amanhã.

Desenvolvimento Psicopata - Qualidade Total
Twitter
Infoblogs - A vitrine do seu blog
[Email] [WWW]
franchico
Entusiasta Java

Membro desde: 11/10/2007 13:14:48
Mensagens: 23
Offline

ViniGodoy

Pelo que vi, são otimas informações, vou estudá-las calmamente, não sou tão expert nisso, uma vez que, faz pouco tempo que conheco o java, mas te agradeço de coração e espero poder contar contigo para futuras dúvidas.

Um Abraço.

"voce é responsável por todos os seus atos, e por todo o seu estado de espirito"
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline

celso.martins wrote:
Vini, aquela solução com while que eu passei, não contaria os caracteres do arquivo, independentemente de qualquer variação, mencionada naquela sua ótima explicação, mensagens atrás?


Se o encoding do seu reader bater com o encoding do arquivo, sim.
Mas postei o artigo porque normalmente não sabemos exatamente nem o que estamos contando... e isso pode ser um problema sério.

Por exemplo, se você, na intenção de ficar no baixo nível, usasse um stream no lugar do reader, estaria também contando bytes, não caracteres. E, como está lá em cima, certos caracteres iguais tem representações diferentes.


This message was edited 1 time. Last update was at 08/11/2007 13:53:19


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
celso.martins
Virtual Machine Man
[Avatar]

Membro desde: 19/06/2006 13:54:23
Mensagens: 699
Localização: Rio de Janeiro
Offline

ViniGodoy wrote:

Se o encoding do seu reader bater com o encoding do arquivo, sim.
Mas postei o artigo porque normalmente não sabemos exatamente nem o que estamos contando... e isso pode ser um problema sério.

Por exemplo, se você, na intenção de ficar no baixo nível, usasse um stream no lugar do reader, estaria também contando bytes, não caracteres. E, como está lá em cima, certos caracteres iguais tem representações diferentes.



Ótimo artigo por sinal. Bem esclarecedor. Mereceu até a favoritada deste tópico, para uma leitura mais tranquila, na chegada ao lar.

Vlw!

Hoje melhor que ontem e pior que amanhã.

Desenvolvimento Psicopata - Qualidade Total
Twitter
Infoblogs - A vitrine do seu blog
[Email] [WWW]
 
Índice dos Fóruns » Interface Gráfica
Ir para:   
Powered by JForum 2.1.8 © JForum Team