...
This program was compiled with the command javac InputLibrary.java
on a system with Java 1.5.0. When run from the command line with java InputLibrary
, the program will successfully take two characters as input and print them out. However, when run with java InputLibrary < input
, where input
is a file that contains the exact same input, the program throws an IOException
prints "ERROR" because the second call to getChar()
finds no characters to read.
Code Block | ||
---|---|---|
| ||
import java.io.BufferedInputStream; import java.io.IOExceptionEOFException; public final class InputLibrary{ public static char getChar()throws IOExceptionEOFException { BufferedInputStream in = new BufferedInputStream(System.in); int input = in.read(); if(input==-1){ throw new IOException("Premature end of input."EOFException(); } return (char)input; //okay because InputStream guarantees read() will fit in a byte if it is not -1 } public static void main(String[] args)throws{ IOException try{ System.out.print("Enter first initial: "); char first=getChar(); System.out.println("Your first initial is "+first); System.out.print("Enter last initial: "); char last=getChar(); System.out.println("Your last initial is "+last); }catch(EOFException e){ System.out.println("ERROR"); } } } |
Compliant Solution
Create and use only a single BufferedInputStream
on System.in
. This code example stores the BufferedInputStream
as a class variable so all methods can access it. However, if a program were to use this library in conjunction with other input from a user that also needs some buffered wrapper on System.in
, the library would need to be modified so that all code uses the same buffered wrapper instead of creating separate ones.
...
Code Block | ||
---|---|---|
| ||
import java.io.BufferedInputStream; import java.io.IOExceptionEOFException; public final class InputLibrary{ private static BufferedInputStream in = new BufferedInputStream(System.in); public static char getChar()throws IOExceptionEOFException { int input = in.read(); if(input==-1){ throw new IOException("Premature end of input."EOFException(); } in.skip(1); //This linestatement now necessary to go to the next line //inthe theNoncompliant previouscode example code deceptively worked without it return (char)input; //okay because InputStream guarantees read() will fit in a byte if it is not -1 } public static void main(String[] args)throws{ IOException try{ System.out.print("Enter first initial: "); char first=getChar(); System.out.println("Your first initial is "+first); System.out.print("Enter last initial: "); char last=getChar(); System.out.println("Your last initial is "+last); }catch(EOFException e){ System.out.println("ERROR"); } } } |
Risk Assessment
Creating multiple buffered wrappers on an InputStream
can crash the cause unexpected program behavior when the InputStream
is re-directed.
...