• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Java FileInputStream .read() działanie

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
+1 głos
492 wizyt
pytanie zadane 8 grudnia 2019 w Java przez enigmatycznyclay Bywalec (2,450 p.)
zamknięte 24 grudnia 2019 przez enigmatycznyclay

Witam. Mam problem ze zrozumieniem jednego zagadnienia. Przykładowo mam tutaj taki prosty kod wykorzystujący klasę FileInputStream:

import java.io.*;

public class klasa {
    public static void main(String[] args) {
        FileInputStream Fin = null;
        try{
            Fin = new FileInputStream("plik.txt");
        }
        catch(FileNotFoundException exc)
        {
            System.out.println("plik nie istnieje");
        }
        int bajt = 0;
        try {
            bajt = Fin.read();
            while (bajt != -1) {
                System.out.print((char) bajt);
                bajt = Fin.read();
            }
        }
        catch(IOException exc)
        {
            System.out.println(exc.getMessage());
        }
        try {
            Fin.close();
        }
        catch(IOException exc)
        {
            System.out.println(exc.getMessage());
        }
    }
}

Otóż fragmentem którego nie mogę do końca zrozumieć jest to:

System.out.print((char) bajt);

O ile dobrze zrozumiałem metoda read zwraca kolejny bajt danych z pliku, a przecież char zapisywany jest w dwóch bajtach. W jaki więc sposób działa to poprawnie? Czy w zmiennej "bajt" nie powinna zostać umieszczona jedynie połowa tego chara co wywołałoby problemy?

komentarz zamknięcia: Rozwiązane

2 odpowiedzi

+1 głos
odpowiedź 12 grudnia 2019 przez mbabane Szeryf (79,260 p.)
wybrane 24 grudnia 2019 przez enigmatycznyclay
 
Najlepsza

Ogólnie do wczytywania plików tekstowych powinno stosować się Reader'y, co jest zasugerowane w dokumentacji:

https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/io/FileInputStream.html

FileInputStream is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader.

Sam char w Javie jest 16-bitowy i jest dostosowany do Unicode, więcej tutaj:

https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Character.html

W Twoim przypadku jeśli w pliku były znaki, które akurat zajmują 1 bajt (czyli większość znaków na klawiaturze) to wczytało poprawnie. Spróbuj wczytać znak, zakodowany w więcej niz 1 bajcie np. taki

https://www.compart.com/en/unicode/U+0BF7

U mnie Twój kod wczytał trzy znaki, a nie jeden jak faktycznie jest w pliku. To jak wygląda znak, a jak jest reprezentowany w pamięci (zakodowany) to są dwie różne rzeczy.

 

Należy także wyjaśnić dlaczego, read() zwraca int - ponieważ byte ma zakres (-128) do 127, a bajty z pliku są z zakresu 0-255, stąd int.

0 głosów
odpowiedź 10 grudnia 2019 przez bartzdev Użytkownik (780 p.)

Zależy od formatu. Dla przykładu, format ANSI jest reprezentowany przez 8 bitów, co daje 1 bajt.

komentarz 11 grudnia 2019 przez enigmatycznyclay Bywalec (2,450 p.)
Czy to znaczy, ze jeżeli w pliku znalazłyby się znaki kodowane w taki sposób, że jeden znak zajmowałby 2 bajty to wtedy dopiero pojawiłyby się problemy?

Podobne pytania

0 głosów
0 odpowiedzi 545 wizyt
pytanie zadane 27 lutego 2018 w Java przez niezalogowany
+2 głosów
1 odpowiedź 1,351 wizyt
pytanie zadane 13 kwietnia 2017 w Java przez Jakub Norek Użytkownik (560 p.)
0 głosów
2 odpowiedzi 1,432 wizyt
pytanie zadane 3 listopada 2015 w Java przez iwan9449 Pasjonat (20,810 p.)

93,444 zapytań

142,436 odpowiedzi

322,698 komentarzy

62,806 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...