Existe uma maneira fácil de evitar lidar com problemas de codificação de texto?
87
Você realmente não pode evitar lidar com os problemas de codificação de texto, mas existem soluções no Apache Commons:
Reader
para InputStream
:ReaderInputStream
Writer
para OutputStream
:WriterOutputStream
Você só precisa escolher a codificação de sua escolha.
Se você está começando com uma String, também pode fazer o seguinte:
fonte
ReaderInputStream
implementação exigiria menos memória - não deveria haver necessidade de armazenar todos os bytes em uma matriz de uma vez.Bem, um Reader lida com caracteres e um InputStream lida com bytes. A codificação especifica como você deseja representar seus caracteres como bytes, portanto, você não pode realmente ignorar o problema. Quanto a evitar problemas, minha opinião é: escolha um conjunto de caracteres (por exemplo, "UTF-8") e continue com ele.
Em relação a como fazê-lo de fato, como foi apontado, " os nomes óbvios para essas classes são ReaderInputStream e WriterOutputStream . " Surpreendentemente, " eles não estão incluídos na biblioteca Java ", embora as classes 'opostas', InputStreamReader e OutputStreamWriter sejam incluído.
Portanto, muitas pessoas criaram suas próprias implementações, incluindo o Apache Commons IO . Dependendo dos problemas de licenciamento, você provavelmente poderá incluir a biblioteca commons-io em seu projeto ou até mesmo copiar uma parte do código-fonte (que pode ser baixado aqui ).
Como você pode ver, a documentação de ambas as classes afirma que "todas as codificações de conjunto de caracteres suportadas pelo JRE são tratadas corretamente".
NB Um comentário em uma das outras respostas aqui menciona esse bug . Mas isso afeta a classe Apache Ant ReaderInputStream ( aqui ), não a classe Apache Commons IO ReaderInputStream.
fonte
Observe também que, se você está começando com uma String, você pode pular a criação de um StringReader e criar um InputStream em uma etapa usando org.apache.commons.io.IOUtils do Commons IO assim:
Claro que você ainda precisa pensar na codificação do texto, mas pelo menos a conversão está acontecendo em uma etapa.
fonte
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
, o que envolve a alocação de duas cópias adicionais do relatório na memória. Se o relatório for grande, é ruim. Veja minha resposta.Usar:
Dessa forma, não é necessária uma conversão inicial para
String
e depois parabyte[]
, o que aloca muito mais memória heap, caso o relatório seja grande. Ele é convertido em bytes instantaneamente conforme o fluxo é lido, direto do StringBuffer.Ele usa CharSequenceInputStream do projeto Apache Commons IO.
fonte
commons-io 2.0 tem
WriterOutputStream
fonte
Os nomes óbvios para essas classes são ReaderInputStream e WriterOutputStream. Infelizmente, eles não estão incluídos na biblioteca Java. No entanto, o Google é seu amigo.
Não tenho certeza se isso vai resolver todos os problemas de codificação de texto, que são um pesadelo.
Existe um RFE, mas está fechado, não corrige.
fonte
Você não pode evitar problemas de codificação de texto, mas o Apache commons-io tem
Observe que essas são as bibliotecas mencionadas na resposta de Peter de koders.com, apenas links para a biblioteca em vez do código-fonte.
fonte
Você está tentando escrever o conteúdo de um
Reader
para umOutputStream
? Em caso afirmativo, você terá mais facilidade em agrupar oOutputStream
em umOutputStreamWriter
e escrever oschar
deReader
em emWriter
, em vez de tentar converter o leitor emInputStream
:fonte
Um aviso ao usar WriterOutputStream - ele nem sempre lida com a gravação de dados binários em um arquivo corretamente / da mesma forma que um fluxo de saída regular. Eu tive um problema com isso que demorei um pouco para rastrear.
Se você puder, eu recomendo usar um fluxo de saída como sua base, e se você precisar escrever strings, use um wrapper OUtputStreamWriter ao redor do fluxo para fazer isso. É muito mais confiável converter texto em bytes do que o contrário, provavelmente porque WriterOutputStream não faz parte da biblioteca Java padrão
fonte
Você pode usar Cactoos (sem métodos estáticos, apenas objetos):
new InputStreamOf(reader)
new OutputStreamTo(writer)
Você também pode converter o contrário:
new ReaderOf(inputStream)
new WriterTo(outputStream)
fonte
Para ler uma string em um fluxo usando apenas o que o java fornece.
fonte