Exception-Handling im I/O-Bereich?!



  • Socket socket = null;
    OutputStreamWriter osw = null;
    InputStreamReader isw = null;
    
    try
    {
        socket = new Socket(...);
        osw = new OutputStreamWriter(socket.getOutputStream());
        isw = new InputStreamReader(socket.getInputStream());
    
        // do smth
    }
    catch(final IOException ex)
    {
        // do error handling
    }
    finally
    {
        try
        {
             if(isw != null)
                 isw.close();
        }
        catch(final IOException ex)
        {
            // do error handling
        }
        finally
        {
            try
            {
                if(osw != null)
                    osw.close();
            }
            catch(final IOException ex)
            {
               // do error handling
            }
            finally
            {
                try
                {
                    if(socket != null)
                        socket.close();
                }
                catch(final IOException ex)
                {
                   // do error handling
                }
            }
        }
    }
    

    Ist das wirklich deren ernst? 😮 😞

    MfG SideWinder



  • 🤡



  • Und was hast du in petto? Wie geht's "schön"?

    MfG SideWinder



  • Immer, wenn da // do error handling steht, habe ich ein Problem, weil ich nicht weiß, was da gemacht wird. Ich nehme an, die meisten sind eh kritisch.

    Socket socket = null;
    OutputStreamWriter osw = null;
    InputStreamReader isw = null;
    
    try
    {
        socket = new Socket(...);
        osw = new OutputStreamWriter(socket.getOutputStream());
        isw = new InputStreamReader(socket.getInputStream());
    
        // do smth
    }
    catch(final IOException ex)
    {
        // do error handling
    }
    finally
    {
        try
        {
             if(isw != null)
                 isw.close();
             if(osw != null)
                 osw.close();
             if(socket != null)
                 socket.close();
        }
        catch(final IOException ex)
        {
            // do error handling // kritisch
        }
    }
    


  • Eine Exception in isw.close() verhindert dann aber osw.close() und socket.close()?

    MfG SideWinder



  • Leider geht's nicht schöner, nur bisschen ausgedünnter:

    Socket s = new Socket();
            OutputStreamWriter osw = null;
            InputStreamReader isw = null;
    
            try {        
                osw = new OutputStreamWriter(s.getOutputStream());
                isw = new InputStreamReader(s.getInputStream());
            } catch(IOException e) {
    
            } finally {
                try {
                    if(osw != null) osw.close();
                } catch (IOException e) {}
                try {
                    if(isw != null) isw.close();
                } catch(IOException e) {}
                try {
                    s.close();
                } catch(IOException e) {}
            }
    

    Meine ultimative Antwort ist, nimm Scala! XD

    import java.net.Socket
    import java.io.IOException
    import java.io.InputStreamReader
    import java.io.OutputStreamWriter
    
    object App {
      def main(arg: Array[String]) {
        var s = new Socket("127.0.0.1", 80)
        var osw = new OutputStreamWriter(s.getOutputStream())
        var isw = new InputStreamReader(s.getInputStream())
        isw.close()
        osw.close()
        s.close()
      }
    }
    


  • //Dieser Code war auch falsch.



  • SideWinder schrieb:

    Eine Exception in isw.close() verhindert dann aber osw.close() und socket.close()?
    MfG SideWinder

    Ja, Fehler von mir.



  • Was mir auch furchtbar schmerzt ist dieses Anlegen von den Variablen im Funktionskopf. Fürchterlich.

    MfG SideWinder



  • -.-



  • Ich kann aber nicht Scala verwenden und eine solche close()-Methode, wenn auch schön, ist erst ab JDK7 möglich. Socket implementiert nämlich dummerweise nicht Closeable...

    MfG SideWinder



  • try {
        Socket socket = new Socket(...);
        try {
            OutputStreamWriter osw = new OutputStreamWriter(socket.getOutpoutStream());
            try {
                InputStreamReader isw = new InputStreamReader(socket.getInputStream());
                try {
                    // do smth
                } finally {
                    isw.close();
                }
            } finally {
                osw.close(),
            }
        } finally {
            socket.close();
        }
    } catch(final IOException exc) {
        // do error handling
    }
    


  • @OhneName: das sieht ja geradezu hübsch aus. Springt er da bei mehreren Fehlern öfters in den catch-Block, ja? Oder nur einmal und die restlichen finally verlieren sich?

    Edit: Also bspw. osw.close -> catch -> finally socket -> socket.close -> abermals catch?

    Oder: osw.close -> catch -> baba (finally socket wird nie ausgeführt)

    MfG SideWinder



  • Ich glaube er landet nur einmal im catch-Block, also wenn doSmth eine Exception wirft und anschließend isw.close() ebenfalls eine, dann wird erstere von letzerer verdeckt. Das kann man als Nachteil sehen, da man den ursprünglichen Fehler evtl. nicht zu Gesicht bekommt. Andererseits sehe ich nicht ein warum ich solch furchtbare Konstrukte wie in deinem ersten Post schreiben sollte, wenn doch ein close() nahezu nie eine Exception wirft. Ob das wirklich so abläuft hab ich noch nicht ausprobiert, aber vom Gefühl her müsste es so sein.

    Edit:
    doSmth throws Exception -> finally isw.close() -> finally osw.close() -> finally socket.close() -> catch Exception
    aber
    doSmth throws Exception -> finally isw.close() throws AnotherException -> finally osw.close() -> finally socket.close() -> catch AnotherException
    (und Exception dürfte verloren gegangen sein)

    Wäre vielleicht echt mal ne gute Idee zu überprüfen ob das wirklich so abläuft.



  • -.-



  • public class Test {
    	public static void main(String[] args) {
    		try {
    			try {
    				try {
    					throw new Exception("inner exception");
    				} finally {
    					System.err.println("inner try finally");
    					throw new Exception("inner try finally exception");
    				}
    			} finally {
    				System.err.println("outer try finally");
    			}
    		} catch(Exception ex) {
    			System.err.println("catch Exception: " + ex.getMessage());
    		}
    	}
    }
    

    ->

    inner try finally
    outer try finally
    catch Exception: inner try finally exception
    

    Außerdem gibt's ne Warnung beim Kompilieren: finally block does not complete normally



  • @SideWinder: RTFM

    Closing this socket will also close the socket's InputStream and OutputStream.


Anmelden zum Antworten