Szkolenia programowania we Wrocławiu
Kurs Java Podstawy - rozszerzony

Rozwiązanie 1.16

Rozwiązanie do zadania 1.16 o treści:

Korzystając z własnego buforowania przekopiuj dane znajdujące się w pliku binarnie.txt do przekopiowane.txt. Dodatkowo zlicz ilość skopiowanych bajtów.

W tym zadaniu korzystać można z dowolnego strumienia opisanego w lekcji. Dla przykładu użyłem tutaj DataInputStream i DataOutputStream.

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class KopiowanieBinarne {

	public static void main(String[] args) {
		DataInputStream strumieńWejściowy = null;
		DataOutputStream strumieńWyjściowy = null;

		try {
			strumieńWejściowy = new DataInputStream(new FileInputStream("binarnie.txt"));
			strumieńWyjściowy = new DataOutputStream(new FileOutputStream("przekopiowane.txt"));
		} catch (FileNotFoundException e) {
			System.out.println("Nie znaleziono takiego pliku");
		}

		int ilośćSczytanychBajtów = 0;
		int całkowitaIlośćBajtów = 0;
		byte[] bufor = new byte[1024];

		try {
			while ((ilośćSczytanychBajtów = strumieńWejściowy.read(bufor)) != -1) {
				strumieńWyjściowy.write(bufor, 0, ilośćSczytanychBajtów);
				całkowitaIlośćBajtów += ilośćSczytanychBajtów;
			}
		} catch (IOException e) {
			System.out.println("Bład wejścia-wyjścia");
		}

		try {
			if(strumieńWejściowy != null) strumieńWejściowy.close();
			if(strumieńWyjściowy != null) strumieńWyjściowy.close();
		} catch (IOException e) {
			System.out.println("Błąd zamykania strumieni");
		}

		System.out.println(całkowitaIlośćBajtów);
	}

}

Komentarze

Komentarze zamknięte. Zapraszamy do grupy na Facebooku
pawel

na czym polega (jak działa, co nam daje) IOException??

Dawid Kunert

Korzystając ze strumieni jesteśmy zobowiązani przechwycić lub "wyrzucić" wyjątek IOException(po którym dziedziczą wszystkie wyjątki wejścia-wyjścia). Projektanci Javy poprzez taką decyzję "zabezpieczyli" nas przed niepowołanym błędem, który spowodowany jest użyciem metod zawartych w klasach strumieniowych. Więcej o wyjątkach: Lekcja 1, Lekcja 2

Janosch

Trochę to zagmatwane i nie wystarczająco zostały wyjaśnione zagadnienia poruszane na lekcji, a które znajdują się w rozwiązaniu. Problemem dla mnie było nawet zaczęcie tego zadania, za mało przejrzystych przykładów jak w poprzednich lekcjach (np. w lekcji "Zapis i odczyt z plików", gdzie można było sobie przyswoić tą wiedzę, gdzie teoria była podparta solidnymi przykładami, a z zadaniem nie było problemów),
Tutaj nie bardzo mogę zrozumieć np.:
- DataInputStream strumieńWejściowy = null; - dlaczego null?
- byte[] bufor = new byte[1024]; (do czego ma się bufor? Czy jest to długość tak jakby pamięci, do której chcemy wrzucić dane z pliku? Jeżeli tak to skąd wiemy jaką wartość tutaj dobrać? Na jakiej podstawie wprowadziłeś 1024?
- Offset jest tutaj 0? Czy znając długość pliku, i jeżeli wprowadzimy ją jako offset to znaczy, że będziemy dopisywali do pliku kolejne rzeczy?
Generalnie przydałoby się jakieś też prostsze zadanie, które łatwiej byłoby ewentualnie przeanalizować w razie problemów ze swoim rozwiązaniem.
Dlaczego ilośćSczytanychBajtów = strumieńWejściowy.read(bufor)) != -1 jest porównywane do -1?
Poza tym kurs świetny!

Dawid Kunert

Masz rację. Postaram się podać więcej informacji na temat tego zadania oraz wstawię inny, łatwiejszy przykład. Dziękuję za zwrócenie uwagi :)

snt.banzai

"KopiowanieBinarne kopiowanie = new KopiowanieBinarne()" - wirtualna maszyna zwraca mi błąd z komunikatem Cannot Find Symbol. Jaki jest angielski odpowiednik?

I jeszcze nie mogę dojść na jakiej zasadzie nastąpiło przypisanie obu plików do Stringów plikWejściowy/plikWyjściowy.

Dawid Kunert

Zapomniałem, że to zagadnienie będzie dopiero w kolejnych lekcjach(programowanie obiektowe). Już to zmieniłem :)

snt.banzai

tak apropos - odkryłem coś takiego

http://wazniak.mimuw.edu.pl/index.php?title=PO_Wstęp_do_Javy

Też bardzo przydatne dla newbies.

pneumonia

Mam małe pytanko? Czy można zrobić to bez DataInputStream i DataOutputStream. Ja napisałem tak i działa:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Binarne2{
public static void main(String[] args){

FileOutputStream wyjscie = null;
FileInputStream wejscie = null;

try{
wyjscie = new FileOutputStream("przekopiowane.txt");
wejscie = new FileInputStream("binarnie.txt");
} catch (FileNotFoundException e){
System.out.println("Nie znaleziono pliku");
}

try{
byte[] bufor = new byte[1];
int b = 0;
while (wejscie.read(bufor) != -1){
wyjscie.write(bufor);
b++;
}
System.out.println("Liczba bajtów to: "+b);
}

catch (IOException e){
}
try{
if(wyjscie != null)
wyjscie.close();
} catch (IOException e){
System.out.println("Blad zamykania strumienia");
}

}
}

Może warto jakoś podkreślić kiedy używamy DataInputStream, poza tym dziękuję za świetny kurs!

Dawid Kunert

Oczywiście, że można to zrobić dowolną z opisanych w tej lekcji klas. W tym rozwiązaniu chciałem jedynie pokazać sposób użycia DataInputStream w kodzie. Co do stosowania tych klas. Data stosujemy w przypadku, gdy chcemy pracować np. na intach czy Stringach w naszym programie, a zwykły Input/Output na bajtach. Co do bufora wielkości 1, to dziwne rozwiązanie, lecz zgodne z poleceniem :)