Binarny zapis i odczyt plików

0

Witam próbuję zrozumień jak są zapisywane dane w pliku przy pomocy

  1. FileOutputStream
  2. DataOutputStraem
    w 1 mam tablicę typu byte która jest strumieniem jak zapisuję jakieś dane i odpalam plik notatnikiem to mam normalnie dane które zapisałem
    natomiast jak zapisuję 2 to w pliku txt jest to jakoś dziwnie zapisane (jak przy serializacji) czemu tak się dzieje, oraz nie wiem czy robię coś źle jak coś zapiszę przez 2 i chcę odczytać przez FileInputStream do bufora (tablica byte) to odczytuje mi właśnie ten dziwny kod a nie normalny tekst. Czemu tak się dzieje. Ps nie interesuje mnie odpowiedź "bo tak" jestem zbyt ciekawski :)
0

Skoro zapisujesz korzystając z DataOutputStream, to czytaj korzystając z DataInputStream.
Zapisywanie za pośrednictwem DataOutputStream zapisuje do pliku kody ASCII.

0

to czemu plik wygląda tak dziwnie? Jak zapisuję przez FileOutputStream a odczytuję przez FileInputStream (sprawdziłem to, w buforze mam kody ASCII) to w pliku są normalne litery. Dlaczego tak się dzieje?

0

Który plik wygląda dziwnie? Jeśli zapisujesz tablicę byte[] bajty metodą write(bajty) z klasy FileOutputStream lub metodą write(bajty,0.bajty.length) z klasy DataOutputStream to pliki są identyczne.
Których metod używasz do czytania?

0

Wtedy tak, wyglądają identycznie.
ale tu

DataOutputStream save;
	try {
			save = new DataOutputStream(new FileOutputStream("a.txt"));
			save.writeInt(tab.length);
			save.writeUTF("\n");
			save.writeInt(tab[0].length);
			save.writeUTF("\n");
			save.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

I otrzymuję w txt http://i66.tinypic.com/o6e73t.png

0

W pierwszym poście pisałeś o zapisywaniu tablicy bajtów, który wiersz w powyższym kodzie odpowiada za zapisywanie tablicy bajtów?
Pliki graficzne dołączaj do postu.

0

Sorki błąd logiczny. Jak zapisuję tablicę bajtów przez DataOutputStream lub FileOutputStream to pliki są identyczne. Chcę się dowiedzieć czemu jak zapisuję dane przez DataOutputStream metodą wtriteInt() to plik wygląda tak dziwnie. Ale jak odczytuję prze DataInputStream metodą readInt() to odczytuje prawidłowo. Tylko chcę się dowiedzieć skąd taka różnica w pliku jest

0

Nie rozumiem Twoich rozterek, jak zapisujesz tablicę bajtów metodą write(bajty,0.bajty.length), to każda pozycja z tablicy zajmuje jeden bajt, jak zapiszesz pierwszy bajt z tej tablicy metodą writeInt(bajty[0]) to on zajmie cztery bajty (pierwsze trzy będą zerowe).

0

już rozumiem jak zapisałem liczbę 4 to dostałem dziwny znak dlatego że ta liczba została zapisana 0000... 0010 i to jest kod ascii jakieś znaku (ten co się pojawił w notatniku)

1

OK, jeśli masz tablicę bajtów, która ma 3 elementy i wygląda tak: (65, 66, 67)
to w tym momencie nie ma znaczenia, jak zapiszesz ten plik. Ale jeśli masz tablicę bajtów, która ma 3 elementy i wygląda tak: (0, 1, 2) to już jest różnica. Dlaczego? Dlatego, że nie wiesz, czym różni się plik tekstowy od binarnego. Plik tekstowy, to taki plik, który składa się jedynie z tekstu (widzialnych znaków). Możesz go otworzyć zwykłym notatnikiem i po prostu z niego czytać tekst. To jest plik tekstowy.

Plik binarny, to plik, który składa się też z niewidocznych znaków (taki utworzyłeś przez DataOutputStream).
Każdy znak ma swój kod ASCII. Teraz spójrz jeszcze raz na początek mojego posta - masz tam tą tablicę składającą się z 3 elementów: 65, 66, 67. Co to są? Jakieś inty, tak? Zgadza się. Ale jeśli te inty zapiszesz do pliku (używając WriteInt), to w pliku będą trzy liczby: 65, 66 i 67. Przypadkiem złożyło się tak, że kod ASCII 65 odpowiada literze A. Dlatego, jeśli taki plik otworzysz w notatniku, zobaczysz ABC.
Zrób teraz coś takiego. Nigdy więcej nie używaj Windowsowego Notatnika.

Uruchom sobie Total Commandera (jak nie masz, to ściągnij i tak Ci się przyda). Znajdź w nim plik, który stworzył Twój program. Podświetl go i wciśnij F3. Otworzy Ci się takie okienko z zawartością pliku.Teraz z menu Opcje wybierz "Heksadecymalnie". I dopiero teraz widzisz faktyczną zawartość pliku. To okno składa się z trzech kolumn. W pierwszej masz adres w pliku pierwszego znaku w danym rzędzie, np: "00000000:"
W drugiej kolumnie masz faktyczną zawartość pliku. Twój plik składa się z liczb. Te liczby są w postaci szesnastkowej (heksadecymalnej). Gdy wpisywałeś do pliku znak '\n' to tak naprawdę wpisywałeś znak o kodzie ASCII 10 (znak nazywa się "new line"). Jeśli wpisywałeś do pliku liczbę 27, to tak naprawdę wpisałeś znak o kodzie ASCII 27, czyli escape.

Trzecia kolumna w tym okienku to jest PRÓBA wypisania Ci tekstowej części pliku binarnego. Czyli tu następuje zamiana widocznych znaków ASCII (np. 65) na znak rozpoznawany przez człowieka - A. Kropka w tym przypadku oznaczać może kropkę (znak '.') lub znak niedrukowany. np. o kodzie ASCII 10.

Wszystkie kody podałem w formie dziesiętnej, a nie szesnastkowej.

Nie wiem, czy coś Ci rozjaśniłem, czy jeszcze bardziej zagmatwałem, ale nie potrafię teraz na szybko lepiej tego wytłumaczyć. Jeśli dalej nie ogarniasz, to zapraszam na priv.

0
OK, jeśli masz tablicę bajtów, która ma 3 elementy i wygląda tak: (65, 66, 67)
to w tym momencie nie ma znaczenia, jak zapiszesz ten plik. Ale jeśli masz tablicę bajtów, która ma 3 elementy i wygląda tak: (0, 1, 2) to już jest różnica

Nieprawda, nie ma żadnej różnicy.

Teraz spójrz jeszcze raz na początek mojego posta - masz tam tą tablicę składającą się z 3 elementów: 65, 66, 67. Co to są? Jakieś inty, tak? Zgadza się
Ale jeśli te inty zapiszesz do pliku (używając WriteInt), to w pliku będą trzy liczby: 65, 66 i 67

Dwie nieprawdy, elementy 65,66,67 to są bajty, nie inty. Po ich zapisaniu w pliku będzie 12 liczb: 0,0,0,65,0,0,0,66,0,0,0,67.

0

jak zapisuję liczbę 37 przez writeInt() to zapisuję 00100101 tylko że na 32 bitach
jak zapisuję tekst AB przez writeUTF() to zapisuję 0100 0001 0100 0010
A B
Jak notatnik odpala to odczytuje tego inta 00100101 jako znak %
a tekst odczyta jako AB dobrze mówię?

0

@bogdans: Doprawdy? To teraz na poparcie swojej tezy zrób taki program i przedstaw nam wnioski.

0
Masterpc96 napisał(a):

jak zapisuję liczbę 37 przez writeInt() to zapisuję 00100101 tylko że na 32 bitach
jak zapisuję tekst AB przez writeUTF() to zapisuję 0100 0001 0100 0010
A B
Jak notatnik odpala to odczytuje tego inta 00100101 jako znak %
a tekst odczyta jako AB dobrze mówię?

Zgadza się. Ale nie do końca. Gdybyś użył metody writeANSI (jeśli taka istnieje), to wtedy byłaby to prawda. Jeśli zapisujesz przez UTF, to każdy znak(w sensie tekst) zajmuje dwa bajty, a nie jeden. W tym wypadku drugim znakiem litery będzie po prostu 0000 0000. Czyli nie dostaniesz: 0100 0001 0100 0010 (AB), tylko: 0100 0001 0000 0000 0100 0010 0000 0000 co w edytorze (np. Total Commander) zobaczysz jako

A.B.

Zwróć uwagę na te kropki. Notatnik oczywiście pokaże Ci AB, ale jak już mówiłem - nie używaj Notatnika do takich rzeczy.

0

Czyli oprócz dodania dodatkowego bajtu mam rację

1 użytkowników online, w tym zalogowanych: 0, gości: 1