Periksa baris untuk karakter yang tidak dapat dicetak saat membaca file teks

Program saya harus membaca file teks - baris demi baris. File dalam UTF-8. Saya tidak yakin apakah file tersebut benar - mungkin berisi karakter yang tidak dapat dicetak. Apakah mungkin memeriksanya tanpa pergi ke level byte? Terima kasih.


person user710818    schedule 14.09.2011    source sumber
comment
Apakah Anda ingin memeriksa satu baris, atau seluruh file?   -  person Eran Zimmerman Gonen    schedule 14.09.2011
comment
Apakah dijamin baris feednya benar?   -  person Tarnschaf    schedule 14.09.2011
comment
periksa satu baris. Ya, umpan baris sudah benar.   -  person user710818    schedule 14.09.2011
comment
Apakah yang Anda maksud adalah karakter yang tidak dapat dicetak dengan font tertentu? Ada karakter yang tidak terdefinisi dalam font apa pun. Ini mungkin hal yang sama.   -  person Peter Lawrey    schedule 14.09.2011


Jawaban (8)


Jika Anda ingin memeriksa suatu string memiliki karakter yang tidak dapat dicetak, Anda dapat menggunakan ekspresi reguler

[^\p{Print}]
person Peter Lawrey    schedule 14.09.2011
comment
Namun, hal ini mencakup karakter spasi dan tab dalam rangkaian karakter non-cetak Anda sementara karakter tersebut memengaruhi tempat kata di halaman. - person bernard paulus; 06.09.2013

Buka file dengan FileInputStream, lalu gunakan InputStreamReader dengan UTF-8 Charset untuk membaca karakter dari aliran, dan menggunakan BufferedReader untuk membaca baris, mis. melalui BufferedReader#readLine, yang akan memberi Anda rangkaian. Setelah Anda memiliki string, Anda dapat memeriksa karakter yang menurut Anda tidak dapat dicetak.

Misalnya. (tanpa pemeriksaan kesalahan), menggunakan coba-dengan-sumber daya (yang agak modern dalam versi Java):

String line;
try (
    InputStream fis = new FileInputStream("the_file_name");
    InputStreamReader isr = new InputStreamReader(fis, Charset.forName("UTF-8"));
    BufferedReader br = new BufferedReader(isr);
) {
    while ((line = br.readLine()) != null) {
        // Deal with the line
    }
}
person T.J. Crowder    schedule 14.09.2011
comment
Atau, untuk satu langkah lebih mudah, buka file dengan FileReader dan gunakan BufferedReader untuk membaca baris. - person Warren Dew; 28.04.2014
comment
@stviper: Dan sekarang tahun 2015, saya telah memperbaruinya untuk menggunakan sumber daya coba-dengan, jauh lebih bersih. :-) - person T.J. Crowder; 07.01.2015
comment
@abhisheknaik96: Terima kasih atas hasil edit Anda, tetapi hanya bit isr yang benar; () seharusnya menjadi (), bukan {}, dan titik koma terakhir tidak diperlukan (tetapi diperbolehkan, jadi saya tinggalkan -- lebih sesuai dengan baris di atasnya). - person T.J. Crowder; 14.04.2015

Meskipun tidak sulit melakukan ini secara manual menggunakan BufferedReader dan InputStreamReader, saya akan menggunakan Guava:

List<String> lines = Files.readLines(file, Charsets.UTF_8);

Anda kemudian dapat melakukan apa pun yang Anda suka dengan garis-garis itu.

EDIT: Perhatikan bahwa ini akan membaca seluruh file ke dalam memori sekaligus. Dalam kebanyakan kasus, hal ini sebenarnya baik-baik saja - dan tentunya lebih sederhana daripada membacanya baris demi baris, memproses setiap baris saat Anda membacanya. Jika itu adalah file yang sangat besar, Anda mungkin perlu melakukannya sesuai dengan T.J. jawaban Crowder.

person Jon Skeet    schedule 14.09.2011
comment
Guava juga mengusulkan metode dengan panggilan balik Files.readLines(File file, Charset charset, LineProcessor‹T› callback) - person Vlagorce; 21.08.2012
comment
Jika tujuannya adalah untuk memproses baris demi baris, menggunakan BufferedRead semudah itu. Menambahkan ketergantungan perpustakaan lain hanya untuk membaca baris juga berlebihan, sementara perpustakaan inti Java sudah mendukungnya. - person user172818; 26.12.2012
comment
@ user172818: Tidak, ini tidak sesederhana... setidaknya tidak jika Anda tidak menggunakan Java 7 dengan pernyataan coba-dengan-sumber dayanya. Selain itu, saya akan kagum dengan program Java non-sepele mana pun yang tidak dapat memanfaatkan Guava di banyak tempat. Ini perpustakaan yang hebat, dan saya tidak akan bisa hidup tanpanya. - person Jon Skeet; 27.12.2012

Baru tahu bahwa dengan Java NIO (java.nio.file.*) Anda dapat dengan mudah menulis:

List<String> lines=Files.readAllLines(Paths.get("/tmp/test.csv"), StandardCharsets.UTF_8);
for(String line:lines){
  System.out.println(line);
}

daripada berurusan dengan FileInputStreams dan BufferedReaders...

person McIntosh    schedule 11.10.2012
comment
Sekadar ingin menambahkan, java.nio.file.* tersedia sejak JDK 7 - person Jifeng Zhang; 14.05.2013
comment
Mungkin ada baiknya menyebutkan dokumen untuk File. readAllLines : metode ini ditujukan untuk kasus sederhana yang memudahkan membaca semua baris dalam satu operasi. Ini tidak dimaksudkan untuk membaca file besar - person Remi Mélisson; 18.03.2014
comment
@fabian Anda benar, saya menggunakan ini sepanjang waktu :) - person McIntosh; 27.08.2019

Bagaimana di bawah ini:

 FileReader fileReader = new FileReader(new File("test.txt"));

 BufferedReader br = new BufferedReader(fileReader);

 String line = null;
 // if no more lines the readLine() returns null
 while ((line = br.readLine()) != null) {
      // reading lines until the end of the file

 }

Sumber: http://devmain.blogspot.co.uk/2013/10/java-quick-way-to-read-or-write-to-file.html

person xproph    schedule 21.10.2013
comment
Tidak - hapus ini - Anda menggunakan pengkodean default - dan memasuki dunia yang penuh penderitaan. - person Mr_and_Mrs_D; 17.06.2014

Saya dapat menemukan cara berikut untuk melakukannya.

private static final String fileName = "C:/Input.txt";

public static void main(String[] args) throws IOException {
    Stream<String> lines = Files.lines(Paths.get(fileName));
    lines.toArray(String[]::new);

    List<String> readAllLines = Files.readAllLines(Paths.get(fileName));
    readAllLines.forEach(s -> System.out.println(s));

    File file = new File(fileName);
    Scanner scanner = new Scanner(file);
    while (scanner.hasNext()) {
        System.out.println(scanner.next());
    }
person Kumar Abhishek    schedule 15.04.2016

Jawaban oleh @T.J.Crowder adalah Java 6 - di Java 7 jawaban yang valid adalah jawaban dari @McIntosh - meskipun penggunaan Charset untuk nama UTF -8 tidak disarankan:

List<String> lines = Files.readAllLines(Paths.get("/tmp/test.csv"),
    StandardCharsets.UTF_8);
for(String line: lines){ /* DO */ }

Mengingatkan banyak cara Jambu Biji yang diposting oleh Skeet di atas - dan tentu saja peringatan yang sama berlaku. Artinya, untuk file besar (Java 7):

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
for (String line = reader.readLine(); line != null; line = reader.readLine()) {}
person Mr_and_Mrs_D    schedule 17.06.2014
comment
Jawaban yang valid untuk Java 6 tetap valid untuk Java 7. - person user207421; 27.08.2019
comment
@ user207421 padahal tidak ada cara yang lebih baik untuk melakukannya - person Mr_and_Mrs_D; 30.08.2019

Jika setiap karakter dalam file dikodekan dengan benar dalam UTF-8, Anda tidak akan kesulitan membacanya menggunakan pembaca dengan pengkodean UTF-8. Terserah Anda untuk memeriksa setiap karakter file dan melihat apakah Anda menganggapnya dapat dicetak atau tidak.

person JB Nizet    schedule 14.09.2011