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

Pojawiajacy sie wyjatek Stream Closed

Aruba Cloud - Virtual Private Server VPS
0 głosów
271 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,260 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,260 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ź 487 wizyt
pytanie zadane 29 listopada 2017 w Java przez newUser Użytkownik (520 p.)
0 głosów
1 odpowiedź 485 wizyt
pytanie zadane 3 września 2017 w Java przez plkpiotr Stary wyjadacz (12,420 p.)
0 głosów
1 odpowiedź 1,644 wizyt

93,335 zapytań

142,330 odpowiedzi

322,410 komentarzy

62,670 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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...