Lettura di un file ASCII con FileChannel e ByteArrays
-
01-07-2019 - |
Domanda
Ho il codice seguente:
String inputFile = "somefile.txt";
FileInputStream in = new FileInputStream(inputFile);
FileChannel ch = in.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE); // BUFSIZE = 256
/* read the file into a buffer, 256 bytes at a time */
int rd;
while ( (rd = ch.read( buf )) != -1 ) {
buf.rewind();
for ( int i = 0; i < rd/2; i++ ) {
/* print each character */
System.out.print(buf.getChar());
}
buf.clear();
}
Ma i caratteri vengono visualizzati su ?.Questo ha qualcosa a che fare con Java che utilizza i caratteri Unicode?Come posso correggerlo?
Soluzione
Devi sapere qual è la codifica del file e quindi decodificare ByteBuffer in CharBuffer utilizzando quella codifica.Supponendo che il file sia ASCII:
import java.util.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
public class Buffer
{
public static void main(String args[]) throws Exception
{
String inputFile = "somefile";
FileInputStream in = new FileInputStream(inputFile);
FileChannel ch = in.getChannel();
ByteBuffer buf = ByteBuffer.allocateDirect(BUFSIZE); // BUFSIZE = 256
Charset cs = Charset.forName("ASCII"); // Or whatever encoding you want
/* read the file into a buffer, 256 bytes at a time */
int rd;
while ( (rd = ch.read( buf )) != -1 ) {
buf.rewind();
CharBuffer chbuf = cs.decode(buf);
for ( int i = 0; i < chbuf.length(); i++ ) {
/* print each character */
System.out.print(chbuf.get());
}
buf.clear();
}
}
}
Altri suggerimenti
buf.getChar() prevede 2 byte per carattere ma ne stai memorizzando solo 1.Utilizzo:
System.out.print((char) buf.get());
Modificando la tua dichiarazione di stampa in:
System.out.print((char)buf.get());
Sembra aiutare.
A seconda della codifica di somefile.txt, un carattere potrebbe non essere effettivamente composto da due byte. Questa pagina fornisce ulteriori informazioni su come leggere i flussi con la codifica corretta.
Il problema è che il file system non ti dice la codifica del file, perché non la conosce.Per quanto lo riguarda, è solo un mucchio di byte.È necessario trovare un modo per comunicare la codifica al programma, rilevarla in qualche modo o (se possibile) assicurarsi sempre che la codifica sia la stessa (come UTF-8).
C'è un motivo particolare per cui stai leggendo il file in questo modo?
Se stai leggendo un file ASCII dovresti davvero usare un Reader.
Lo farei qualcosa del tipo:
File inputFile = new File("somefile.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
E poi usa uno dei due readLine
o simili per leggere effettivamente i dati!
Sì, è Unicode.
Se hai 14 caratteri nel tuo file, ottieni solo 7 '?'.
Soluzione in sospeso.Ancora pensando.