Podczas odczytu pliku tekstowego sprawdź, czy w wierszu nie znajdują się Znaki niedrukowalne

Mój program musi odczytywać pliki tekstowe-linia po linii. Pliki w UTF-8. Nie jestem pewien, czy pliki są poprawne - mogą zawierać znaki niedrukowalne. Czy można go sprawdzić bez przechodzenia na poziom bajtów? Dzięki.

Author: Peter Wippermann, 2011-09-14

8 answers

Jeśli chcesz sprawdzić, czy łańcuch ma znaki niedrukowalne, możesz użyć wyrażenia regularnego

[^\p{Print}]
 15
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-14 09:19:13

Otwórz plik za pomocą FileInputStream, Następnie użyj InputStreamReader z UTF-8 Charset aby odczytać znaki ze strumienia i użyć BufferedReader do czytania wierszy, np. poprzez BufferedReader#readLine, co da ci sznurek. Gdy już masz ciąg znaków, możesz sprawdzić, czy nie są to znaki, które uważasz za drukowalne.

W przeciwieństwie do Javy, Java nie jest w pełni kompatybilna z innymi Javami, ale jest w pełni kompatybilna z Javą.]}
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
    }
}
 121
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-14 07:13:36

Choć nie jest trudno zrobić to ręcznie używając BufferedReader i InputStreamReader, użyłbym Guava :

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

Możesz wtedy robić, co chcesz z tymi wersami.

EDIT: zauważ, że spowoduje to wczytanie całego pliku do pamięci za jednym zamachem. W większości przypadków jest to w porządku - i to z pewnością prostsze niż czytanie linii po linii, przetwarzanie każdej linii tak, jak ją czytasz. Jeśli to ogromny plik, być może będziesz musiał to zrobić w ten sposób, zgodnie z odpowiedzią T. J. Crowdera.

 49
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-14 09:20:06

Właśnie się dowiedziałem, że za pomocą Javy NIO (java.nio.file.*) można łatwo napisać:

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

Zamiast zajmować się FileInputStream s I BufferedReader s...

 42
Author: McIntosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-11 11:17:14

A może poniżej:

 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

 }

Źródło: http://devmain.blogspot.co.uk/2013/10/java-quick-way-to-read-or-write-to-file.html

 11
Author: xproph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 10:37:10

Mogę znaleźć następujące sposoby.

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());
    }
 5
Author: Kumar Abhishek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-15 07:49:57

Odpowiedź @T. J. Crowdera to Java 6 - w Javie 7 poprawna odpowiedź to ta @ McIntosh - chociaż nie zaleca się używania Charset dla nazwy dla UTF -8:

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

Przypomina sposób Guava zamieszczony powyżej przez Skeet - i oczywiście obowiązują te same zastrzeżenia. Oznacza to, że dla dużych plików (Java 7):

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
for (String line = reader.readLine(); line != null; line = reader.readLine()) {}
 3
Author: Mr_and_Mrs_D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 00:52:10

Jeśli każdy znak w pliku jest poprawnie zakodowany w UTF-8, nie będzie problemu z odczytaniem go za pomocą czytnika z kodowaniem UTF-8. Do ciebie należy sprawdzenie każdego znaku pliku i sprawdzenie, czy uważasz go za drukowany, czy nie.

 1
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-14 09:13:21