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

Pojawiajacy sie wyjatek Stream Closed

Object Storage Arubacloud
0 głosów
205 wizyt
pytanie zadane 2 maja 2019 w Java przez bastek Nowicjusz (190 p.)

Witam

Mam problem z pojawiajcym sie wyjatkiem java IOException: Stream closed.Nie za bardzo kumam dlaczego wyskakuje informacja ze strumien jest zamkniety skoro jest uzywana wersja try automatycznie zarzadzajaca zasobami.Czyli close() nastepuje w automacie

import java.io.*;

class BudgClass{
	String nameFile;
	byte choice=0;
	
	
	BudgClass(String strN){
		nameFile = strN;
	}
	
	void showMenu(){	
		System.out.println("\t ==>> Witaj w programie  <<== ");
		System.out.println("\t Wybierz z posrod dostepnych opcji\n");
		System.out.println("1. Dodaj ");
		System.out.println("2. Pokaz");
		System.out.println("3. Zakoncz program ");
	}
	
	byte choice(){
		byte bt;
		String str;
		int x;
		
		try(BufferedReader bf=new BufferedReader(new InputStreamReader(System.in)))
		{				
			do{
					bt=0;
					System.out.print("Twoj wybor: ");
					str = bf.readLine();
					try{
						choice = Byte.parseByte(str);
					}catch(NumberFormatException exc){
						System.out.println("Niepoprawny format");
						bt=-1;
					}
					if(bt!=-1){
						if(choice >=1 && choice <=3)	bt=1;
						else		System.out.println("Brak funkcji.Sprobuj pnownie \n");
						}
			}while(bt!=1);
					
		}catch(IOException exc){
			System.out.println("Wystapil blad wejscia konsoli");
			return -1;
		}
		
		return choice;
	}

	
	
	
	void addInfo(){
		System.out.println("\t ==>> Witaj w programie  <<== ");

		String month,info;
		double expense,sum;
		String str;
		
		info="TAK";
		try (FileWriter fw = new FileWriter(nameFile,true);
				BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
		{
			do{				
				System.out.print("\nPodaj nazwe miesiaca: ");
				month=br.readLine();
			
				month="\n*"+month+"\r\n";
				fw.write(month);
				sum=0;

				do{
					System.out.print("Podaj kolejny element: ");
					info=br.readLine();
					info="\t+"+info+"\t";
					fw.write(info);	
					do{
						System.out.print("Podaj kwote: ");
						info=br.readLine();
						expense=-1;
						try{
							expense=Double.parseDouble(info);
							sum+= expense;
						}catch(NumberFormatException exc){
							System.out.println("Niepoprawny format kwoty.Uzyj kropki jako znaku rozdzielajacego");
						}
					}while(expense== -1);
					info="\t"+ info+"\r\n";
					fw.write(info);
					
					System.out.print("Czy chcesz dodac kolejny element? TAK/NIE ");
					info=br.readLine();
				}while(info.equals("TAK"));
				System.out.println("Suma : "+sum);
				fw.write("\t\t\t\t Suma: "+sum);
				
				System.out.print("Kolejny miesiac? TAK/NIE ");
				info=br.readLine();
				
			}while(info.compareTo("TAK")==0);
			System.out.println("\n**Wyjscie do MENU glownego**");
		} catch(IOException exc){
			System.out.println("Wystapil blad wejscia - wyjscia  "+exc);
		}
		
			
	}
}

class Budget{
	public static void main(String args[])
	throws IOException{
		BudgClass bc = new BudgClass("plik.txt");
		byte nr;
		
		bc.showMenu();				
		nr= bc.choice();
		switch(nr){
			case 1:
				bc.addInfo();
				break;
			case 2:
				break;
			case 3:
				break;
			default:
				System.out.println("## Zamykanie programu ##");
		}
		
	}
}

W metodzie choice() pobieram informacje od uzytkownika w zakresie wyboru konkretnej opcji natomiast w metodzie addInfo() zostaja wczytane informacje z konsoli i zapisywane do pliku.Sprawdzilem juz wywolujac jedna metode bez drugiej jest ok na odwrot tez ok.Jak rozumiem problem jest ze stworzonym strumieniem System.in opakowanym klasa BufferedReader. Oczywiscie program sie dopiero tworzy wiec to wstep.Natomiast nie za bardzo rozumiem dlaczego jest blad.Dokonalem zamiany i jawnie zamknalem jeden i drugi strumien i tak lipa wiec jakby ktos mi podrzucil jakas wskazowke gdzie lezy blad w moim mysleniu

Pzdr

komentarz 3 maja 2019 przez Zibi Obywatel (1,220 p.)

A mogłbyś wrzucić cały stackTrace? Łatwiej będzie zdiagnozować problem.

Zalecam też stosowanie zasady pojedynczej odpowiedzialności (single class responsibility) i lekturę "Czysty kod" wtedy kod będzie łatwiej analizować innym i Tobie po pewnym czasie.

komentarz 4 maja 2019 przez bastek Nowicjusz (190 p.)
Na przyszlosc wrzuce .

Zasade pojedynczej odpowiedzialnosci?Jak bys mogl rozwinac wzgledem tego kodu co masz na mysli.

Jestem ogolnie na poczatkowym etapie uczenia jednak rozwazalem czy moja nastepna lektura przypadkiem nie stanie sie "Czysty Kod" choc uwazalem ze musze przerobic ze 3 -4  ksaizki z javy zeby miec jakas wiedze aby ja wykorzystywac/porzadkowac.Natomiast moze w zwiazku z twoja sugestia  "przestudiuje"ja troche wczesniej skoro to tak kiepsko wyglada :-)

2 odpowiedzi

0 głosów
odpowiedź 3 maja 2019 przez mbabane Szeryf (79,280 p.)
wybrane 4 maja 2019 przez bastek
 
Najlepsza

O ile się nie mylę. Ponieważ używasz System.in to tak naprawdę zostaje zamknięty własnie cały System.in, który jest inicjowany przy starcie aplikacji z automatu. Robiąc jawnie System.in.close() (czy to przez try-with-resources) zamykasz całe standardowe wejście, które jest na starcie wczytywane do zmiennej System.in

Możesz to obejść robiąc raz dla całej aplikacji

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))

i zamknąć to przed skończeniem się programu (robisz po prostu z tego taką zmienną globalną - w tym wypadku nie jest to nic złego, ponieważ masz dobry powód do tego by tak zrobić. Nie da się w dowolnym momencie zamykać i ponownie otwierać standardowego wejścia/wyjścia):

Zerknij na to:

https://stackoverflow.com/questions/33555283/why-is-not-possible-to-reopen-a-closed-standard-stream/33555444

komentarz 4 maja 2019 przez bastek Nowicjusz (190 p.)
Czyli reasumujac uzywajac jednej z metod zamykam strumien System.in dlatego tez druga metoda nie moze utworzyc instacji klasy opakowywujacej  strumien poniewaz strumien ten zostal zamkniety? Jesli dobrze zrozumialem. Ok zatem moje pytanie w informacjach ksiazkowych czy tez z innych zrodlach omawiajacy wejscia-wyjscia w Javie jest zawsze sugestia/zalecenie aby zamykac strumien gdy go nie uzywamy. Z reguly jest  wykonywane jakies dzialanie z uzytkownikiem i on jest zamykany Zatem co w przypadku duzych aplikacji posiadajacych obszerniejsze menu.Takie otworzenie strumienia na poczatku i nie zamykanie go przez praktycznie caly pgm  faktycznie nie jest bledem?Nie powoduje generowania dodatkowych bledów?

Strumien ten moglby zostac tez otwierany przez konstruktor  klasy .Podczas tworzenia obiektu i zamykany przez dodatkowa metode klasy natomiast zastanawiam sie nad poprawnoscia takiego rozwiazania.
komentarz 4 maja 2019 przez mbabane Szeryf (79,280 p.)
Przede wszystkim duże aplikacje nie korzystają z konsoli. A tutaj o to się rozchodzi.

W przypadku np. gniazd sieciowych, połączeń do bazy danych, plików, należy zamykać strumień, jeśli nie jest potrzebny.
+1 głos
odpowiedź 3 maja 2019 przez Zibi Obywatel (1,220 p.)

Zamykanie strumienia następuje w linii:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in))

Rozwiązaniem może być utworzenie tego strumienia raz i używanie go w obu metodach.

A póżniej dopiero ten strumień należy zamknąć.

Podobne pytania

0 głosów
1 odpowiedź 450 wizyt
pytanie zadane 29 listopada 2017 w Java przez newUser Użytkownik (520 p.)
0 głosów
1 odpowiedź 444 wizyt
pytanie zadane 3 września 2017 w Java przez plkpiotr Stary wyjadacz (12,420 p.)
0 głosów
1 odpowiedź 1,086 wizyt

92,551 zapytań

141,397 odpowiedzi

319,528 komentarzy

61,936 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...