Pytanie Java, Unicode, UTF-8 i Windows Command Prompt


Mam plik jar, który powinien odczytać plik zakodowany w UTF-8, który napisałem w edytorze tekstu w systemie Windows i wyświetlić znaki na ekranie. Pod OS X i Linux działa to bezbłędnie. Mam trochę problemów z uruchomieniem go pod Windowsem ... Zdefiniowałem czytnik i program piszący w ten sposób:

FileInputStream file = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(file, "UTF8");

PrintStream writer = new PrintStream(System.out, true, "UTF8");

Zmieniłem także czcionkę wiersza polecenia na Lucida Console i kodowanie znaków do UTF-8 za pomocą chcp 65001, w tej kolejności.

Teraz, kiedy biegnę java -jar Read.jar file.txt, szybka wypluwa to.

áéí
ñóú
[]óú
[]

Jeśli jednak biegnę type file.txt, monit poprawnie wyświetla zawartość pliku.

áéí
ñóú

Próbowałem zapisać plik z BOM i bez niego, ale to nie miało znaczenia. (UTF-8 nie potrzebuje nawet BOM, ponieważ jest to brak endianness, prawda?) Próbowałem kompilacji z javac -encoding utf8 *.java, ale to samo się dzieje.

Nie mam teraz pomysłów. Czy ktoś chce pomóc?


13
2017-08-13 02:23


pochodzenie


Jeśli przekierowujesz wyjście do pliku, czy plik wyjściowy jest taki sam jak plik wejściowy? Jeśli nie, to co się różni? - Harry Johnston
Czy używasz zapisu (bufor, 0, bajtread) do wyprowadzenia danych? - Vamsi Mohan Jayanti
Przekierowanie przez type file.txt > file2.txt tworzy dokładnie ten sam plik ze wszystkimi prawidłowymi znakami. - 425nesp
I write metodą jest zapisywanie do pliku, czyż nie? Napisałem plik wejściowy za pomocą edytora tekstu, a nie poprzez kod. - 425nesp
Miałem na myśli, kiedy piszę to na konsolę, używając piszącego do zapisu na konsoli, używaj bufora odczytu rgt! Teraz robisz coś takiego bajtu [] byteBuff = new byte [10]; int bread = plik.read (byteBuff); writer.write (byteBuff, 0, bread); // - Vamsi Mohan Jayanti


Odpowiedzi:


Strona kodowa 65001 jest zepsuta. Funkcje stdio środowiska wykonawczego MS C zwracają niedokładne liczby bajtów odczytywanych i zapisywanych po uruchomieniu pod 65001, co prowadzi do dziwnych zachowań, takich jak ten.

Nie można go naprawić - nie można niezawodnie korzystać z konsoli Windows do obsługi Unicode I / O z aplikacji korzystających z funkcji C-stdlib-byte-I / O (w tym Java). Możesz go zhakować, wywołując funkcję Win32 API WriteConsoleW, aby pobrać zawartość Unicode bezpośrednio do Konsoli, ale musisz się martwić wykryciem, kiedy naprawdę jest to konsola (nie przekierowana do pliku).

Jest to długotrwałe źródło nieszczęścia, które MS nie wykazuje zainteresowania naprawianiem.


13
2017-08-13 08:34



Czytałem, że wsparcie zostało przerwane gdzieś indziej w Internecie, ale nie chciałem w to uwierzyć. Westchnienie. Niestety, myślę, że masz rację. - 425nesp


Wygląda na to, że mogą to być znaki nowej linii. Kiedy robię znaki nowej linii w standardowym języku angielskim ISO-8859-1, używam tablicy char [], ponieważ znaki "\ r" i "\ n" oraz UNIX / Linux są tylko \ r jako znakiem nowej linii. Wygraj 4 bajty, unix 2 bajty. Nie, w dokumentach API dla klas konwerterów znaków, system konwersji kodowania może zawierać fałszywe bajty pozostawione do wyrzucenia zależne od wymagań kodowania i wielkości znaków.


0
2017-08-13 02:39





Spróbuj użyć BufferReader, aby odczytać twój plik w ten sposób;

   BufferedReader in = new BufferedReader(
       new InputStreamReader(
                  new FileInputStream(file), "UTF8"));

0
2017-08-13 09:23



Dzięki, ale podpowiedź pozostała nieprzyjemna. - 425nesp