Trying to Understand Purpose of a Catch Block for IOException in thePresence of One for FileNotFound

Discussion in 'Java' started by KevinSimonson, Aug 12, 2011.

  1. If I write a piece of code that constructs an object of class
    <PrintWriter> by passing it an object of class <BufferedWriter>,
    constructed by passing _it_ an object of type <FileWriter> (all three
    classes under <java.io>), don't have a <throws> clause, have only a
    <catch> clause for <FileNotFoundException>, and then try to compile
    the code the compiler complains, telling me, "unreported exception
    java.io.IOException java.io.IOException: must be caught or declared to
    be thrown". Of course, if I put a <catch> clause there for
    <IOException>, that fixes the problem and the program compiles just
    fine.

    If, on the other hand, I write a piece of code that constructs an
    object of class <Scanner>, constructed by passing it an object of type
    <File>, don't have a <throws> clause for <FileNotFoundException>, and
    don't put the constructor call in a <try> block at all, I get a
    similar complaint about me not saying anything about exception
    <FileNotFound>.

    Finally, if I have some code that has constructors for _both
    <PrintWriter> and_ <Scanner>, I have to have a <catch> clause for
    _both <IOException> and_ <FileNotFoundException>, in order to keep the
    compiler happy. But in such a situation I have not been able to find
    a way to _actually get <IOException> thrown_! What is the purpose of
    having a <catch> block for <IOException> if nothing I do with my code
    will actually throw an <IOException> that is not a
    <FileNotFoundException>? Or, alternately, is there something I can do
    to _get_ an <IOException> that is not a <FileNotFoundException>
    thrown?

    I would appreciate any information anyone can give me on this.

    Kevin Simonson
     
    KevinSimonson, Aug 12, 2011
    #1
    1. Advertisements

  2. Show us the actual code.
     
    Knute Johnson, Aug 12, 2011
    #2
    1. Advertisements

  3. KevinSimonson

    markspace Guest


    I'm with Knute here: tl;dr, Show us the code!
     
    markspace, Aug 12, 2011
    #3
  4. I've actually written a number of different programs trying to find
    something that I can run that will throw an exception that is a
    <IOException> but not a <FileNotFoundException>. I've tried to open a
    file for input when I don't have read access to the file. I've tried
    to open a file for output when the file exists and I don't have write
    access to the file. I've opened a file for input, done a "chmod u-r
    <filename>" while the program's running, and then tried to close the
    file. I've opened a file for output, done a "chmod u-w <filename>"
    while the program's running, and then tried to close the file. Do any
    of you want me to dig up some of those files?

    Most recently I tried writing a Java program that opens a file but
    then closes it without writing anything to it, that results in an
    empty file, and then opens the same file and tries to read a line from
    it. But that results in a <NoSuchElementException> getting thrown,
    not an <IOException>. I don't think that file will help anyone.

    Perhaps the best bet would be one I wrote back on 8 August:

    import java.io.IOException;
    import java.io.FileNotFoundException;
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.BufferedWriter;
    import java.io.PrintWriter;
    import java.util.Scanner;

    public class Cf
    {
    private static void prompt ( BufferedReader userInput
    , String prmpt)
    {
    System.out.print( prmpt + "? ");
    try
    { userInput.readLine();
    }
    catch (IOException excptn)
    {
    }
    }

    public static void main ( String[] arguments)
    {
    if (arguments.length == 2)
    { int lineCount = 0;
    boolean srcOpnd = false;
    try
    { BufferedReader usrInpt
    = new BufferedReader( new
    InputStreamReader( System.in));
    prompt( usrInpt, "Construct source");
    Scanner source = new Scanner( new File( arguments[ 0]));
    srcOpnd = true;
    prompt( usrInpt, "Construct destination");
    PrintWriter dstntn
    = new PrintWriter
    ( new BufferedWriter( new
    FileWriter( arguments[ 1])));
    String textLine;
    for (;;)
    { prompt( usrInpt, "Call <hasNextLine()>");
    if (! source.hasNextLine())
    { break;
    }
    prompt( usrInpt, "Read line");
    textLine = source.nextLine();
    prompt( usrInpt, "Write line");
    dstntn.println( textLine);
    lineCount++;
    }
    prompt( usrInpt, "Close files");
    dstntn.close();
    source.close();
    prompt( usrInpt, "All done");
    }
    catch (FileNotFoundException excptn)
    { System.out.println();
    System.out.println( "Couldn't open file!");
    System.out.println( "<srcOpnd> == " + srcOpnd + '.');
    }
    catch (IOException excptn)
    { System.out.println();
    System.out.println( "I/O problem with file!");
    System.out.println( "<srcOpnd> == " + srcOpnd + '.');
    }
    }
    else
    { System.out.println( "Usage is\n java Cf <source>
    <destination>");
    }
    }
    }

    Functionally, it copies the contents of a file to another file, but it
    stops at every significant part of the process and prompts for user
    input. It doesn't _require any information_ from the user; all the
    user has to do is hit the <Enter> key; all it does is let the user
    delay execution of certain parts of the program until s/he has changed
    permissions on the original file or the copy if s/he chooses to do so.

    So try running this program and doing various things to the two
    files. If you can find something that actually generates a
    <IOException>, please, _please_, let me know what you did!

    Kevin Simonson
     
    KevinSimonson, Aug 12, 2011
    #4
  5. KevinSimonson

    markspace Guest


    The FileWriter constructor is declared to generate an IOExcpetion. I
    don't have time to mess with it, but it's likely a large variety of
    network file systems could generate an IO error of various types.

    While any other error might be swallowed by the PrintWriter, you are
    briefly exposed to the vagaries file system while that constructor is
    running.
     
    markspace, Aug 12, 2011
    #5
  6. Just speculating: have you tried to read a large file from
    an USB thumbdrive and midway disconnect the drive?

    Warning: that *may* damage the thumbdrive (even physically,
    not just the filesystem on it!), so use an old small one that
    you wont miss in case it's really broken afterwards.
    Removing permissions after the file has been opened doesn't
    ever matter, anyway. Permissions are only checked at open().
     
    Andreas Leitgeb, Aug 12, 2011
    #6
  7. KevinSimonson

    Stefan Ram Guest

    I did not read all of the thread. But if you feel annoyed
    having to write a catch while believing to know that there
    will not be such an exception, try (no pun intended):

    public static void main( final java.lang.String[] args )
    throws java.io.IOException
    { ... }
     
    Stefan Ram, Aug 12, 2011
    #7
  8. Patricia, you were absolutely right! Following up on your puzzlement,
    I rewrote the program I posted, taking out the <import> of
    <FileNotFoundException> and consolidating my <catch> blocks into:

    catch (IOException excptn)
    { System.out.println();
    System.out.println( "Couldn't open file!");
    System.out.println( "<srcOpnd> == " + srcOpnd + '.');
    }

    This works just fine. All I can think of is that when I tried to
    compile a program that just took input the compiler complained about
    <FileNotFound> and when I tried to compile a program that just wrote
    output the compiler complained about <IOException>, so maybe I just
    _assumed_ that a program that both read input and wrote output would
    need both exceptions!

    Anyhow, thanks for pointing me in the right direction.

    Kevin Simonson
     
    KevinSimonson, Aug 12, 2011
    #8
  9. KevinSimonson

    Lew Guest

    Since 'FileNotFoundException' is a subtype of 'IOException', a catch block for the latter will catch the former.

    Another subtype of 'IOException' that is not a super- or subtype of 'FileNotFoundException' is 'EOFException'. You could write a loop to keep reading a file (that is found) past its end to throw 'EOFException'.

    A catch block for 'IOException' will catch both 'FileNotFoundException' and 'EOFException', as well as any other subtype of 'IOException'.
     
    Lew, Aug 12, 2011
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.