Why i can't open second stream in java? - java

Here is my problem.I've made simple input class with methods for getting primitive values from user's keyboard.The problem is that whenever i use this class in my other classes i face the problem that when i made more than one instance of this class i get a problem of the "Close stream".Why is this happening?
For example:i have a main method where i get user's input and decide which object to make,say i can make 4 different objects(4 classes),after i call the objects "set state" method,where i actually set all the states of this object with making second instance of the input class,and then ,when i try to read again the user's input in my main method,i get an exception "Stream closed".
Here is the code of the input class :
public class UserInput {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));;
public int getInt() {
try {
String line;
line = reader.readLine();
return Integer.parseInt(line);
} catch (Exception ex) {
ex.printStackTrace();
return -1;
}
}
public double getDouble() {
try {
String line = reader.readLine();
return Double.parseDouble(line);
} catch (Exception ex) {
return -1;
}
}
public float getFloat() {
try {
String line = reader.readLine();
return Float.parseFloat(line);
} catch (Exception ex) {
return -1;
}
}
public long getLong() {
try {
String line = reader.readLine();
return Long.parseLong(line);
} catch (Exception ex) {
return -1;
}
}
public short getShort() {
try {
String line = reader.readLine();
return Short.parseShort(line);
} catch (Exception ex) {
return -1;
}
}
public String getString() {
try {
String line = reader.readLine();
return line;
} catch (Exception ex) {
return " ";
}
}
public char getChar() {
try {
return (char) reader.read();
} catch (Exception ex) {
return (' ');
}
}
public void close() {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

The standard way for user input is to use a Scanner which already contains methods for reading different kinds of input.
You're not supposed to close the reader, because that will then close System.in which is not what you want.

By calling reader.close(); you are not only closing the reader himself because the call invokes the close() method of the InputStreamReader aswell and therefore closes System.in (which you can not reopen).
A possible Solution would be to use a Scanner as Kayaman pointed out in his answer or to override the close() method like this:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in){#Override public void close(){});

Related

How could I deal with this custom Exception?

I have this bit of code which depends from a custom Exception thrown by a function inside findID() it throws a NoClientFound Exception that I made whenever this mentioned function returns a null (The client does not exist).
The IDE suggests that I shall apply that Exception into the code, but in this bit of code, where I need the ID to be null (unique IDs) I "can't catch that exception" since if I catch it, the function will not be executed as intended.
Question: How I can manage this?
Function with the Exception problem
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
if (findID(c.getID()) == null) {
try (BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));) {
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
} catch (IOException e) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE,
null, "Error appeding data to file" + e);
}
}
} catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
} finally {
}
return addded;
}
Exception Code
public class NoClientFound extends Exception {
private String msg;
public NoClientFound() {
super();
}
public NoClientFound(String msg) {
super(msg);
this.msg = msg;
}
#Override
public String toString() {
return msg;
}
You can catch that exception and handle it accordingly. When you catch NoClientFound exception that means findID(c.getID()) is null. So without handling that in the if block you can handle that within the catch block.
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
// call the function
findID(c.getID());
} catch (NoClientFound ex) {
//handle the NoClientFound exception as you like here
BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
}catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
}finally {
}
return addded;
}
I assume you already have a null check on findID(...)
if( c == null || findID(c.getID()) == null){
throw new NoClientFound("Client not found!");
}else{
//add your file writing operation
}
and Also in NoClientFound class extend it from RuntimeException, not the Exception.
public class NoClientFound extends RuntimeException {
...
}
Caller method:
public void caller(){
Client client = new Client();
client.setId(1);
...
try{
add(client);
}catch(NoClientFound ex){
//client not found then create one for ex...
}
catch(Exception ex){
//somthing else happend
log.error(ex.getmessge());
}
}

Java input/output stream for primitive values

I've been reading about java streams and decided to make a simple input class that will read input from the user(keyboard) and return it back.The problem is that i don't know which stream-class to use for simple,primitive values.I made UserInput class using the DataInputStream ,but noticed that i didn't work,because,as i understood,the DataInputStream supports only bufferedStream,and the problem is that i don't know how to flush the input after i read something(There is no flush method).How do i fix this,or could you suggest me another input stream for primitive values(without casting and using of Integer.valueOf() e.t.c methods).Also,i made UserInput with BufferedReader,but i didn't like it,because i had to use methods like:Double/Integer/Short/etc.valueOf()
Here is the code of my class :
import java.io.*;
import java.util.InputMismatchException;
public class UserInput {
static DataInputStream reader;
public UserInput() {
reader = new DataInputStream(System.in);
}
public int getInt() {
int result = -1;
try {
result = reader.read();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return -1");
}
return result;
}
public double getDouble() {
double result = -1;
try {
result = reader.readDouble();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return -1");
}
return result;
}
public float getFloat() {
float result = -1f;
try {
result = reader.readFloat();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return -1");
}
return result;
}
public long getLong() {
long result = -1l;
try {
result = reader.readLong();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return -1");
}
return result;
}
public short getShort() {
short result = -1;
try {
result = reader.readShort();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return -1");
}
return result;
}
public String getString() {
String result = " ";
try {
result = reader.readUTF();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return empty character ");
}
return result;
}
public char getChar() {
char result = ' ';
try {
result = (char) reader.read();
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Couldn't open buffered.Return empty character ");
}
return result;
}
/**
* Closes the buffer.
*
*/
public void close() {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("Inputstream has been closed.");
}
}
}
I think there's a misunderstanding here - you're treating System.in (which is a stream of characters) as a DataInputStream (which is a stream of bytes - something very different)
If your intention is to read various types from System.in you could just use operations similar to this:
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
System.out.println("Got string: " + s);
double d = scanner.nextDouble();
System.out.println("Got double: " + d);
So your class could be set up like this:
public UserInput() {
scanner= new Scanner(System.in);
}
Otherwise if your intention was to read and write primitives, you'd need to first write those primitives onto a DataOutputStream, which is equivalent to a DataInputStream. The System.in would not be relevant to the exercise in this case.

printing strings doubles and integers from a different file

So I'm new to java and I have to read strings, doubles, and integers from a file and print them out after. This is the error that java is throwing at me:
error: variable declaration not allowed here Scanner file = new
Scanner(line);
what am does it mean?
Scanner file = new Scanner(line);
Fails because a variable named file is already declared above ...
Scanner file = new Scanner(data);
Give one of the scanner variables a different name. There's some other problems with your code, but I assume this is a school assignment so only answered the question you asked.
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.txt"));
String line;
while ((line = br.readLine()) != null) {
String[] splited = line.split(" ");
for (String st: splited) {
if(isInteger(st))
System.out.println("---int--->"+st);
else if(isDouble(st))
System.out.println("---dubl--->"+st);
else if (!st.isEmpty())
System.out.println("---String--->"+st);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static boolean isInteger(String st) {
try {
Integer.parseInt(st);
return true;
} catch (NumberFormatException e) {
return false;
}
}
static boolean isDouble(String str) {
try {
Float.parseFloat(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
This Maybe help you

Using parsed input from text file as parameter for new Event

I've working on an assignment that asks me to alter a method in a class to take content from a textfile and use it to create multiple instances of various subclasses of the Event Class. Here is the text file:
Event=ThermostatNight,time=0
Event=LightOn,time=2000
Event=WaterOff,time=8000
Event=ThermostatDay,time=10000
Event=Bell,time=9000
Event=WaterOn,time=6000
Event=LightOff,time=4000
Event=Terminate,time=12000
The Event=* is the name of the subclass, while time=* is a parameter that is used in the subclass' constructor. The Event class itself is an abstract class and is used for inheritance.
public class Restart extends Event {
Class eventClass;
String eventInput;
Long timeDelay;
public Restart(long delayTime, String filename) {
super(delayTime);
eventsFile = filename;
}
public void action() {
List<String> examples = Arrays.asList("examples1.txt", "examples2.txt", "examples3.txt", "examples4.txt");
for (String example : examples) {
//finding pattern using Regex
Pattern pattern = Pattern.compile(example);
Matcher matcher1 = pattern.matcher(eventsFile);
if (matcher1.find()) {
File file = new File(example);
String line;
try {
FileReader fileReader = new FileReader(file);
Scanner sc = new Scanner(file);
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
sc.useDelimiter("\n");
//Parsing through text
while (sc.hasNext()) {
String s = sc.next();
String[] array1 = s.split(",");
String[] array2 = array1[0].split("=");
eventInput = array2[1];
String[] array3 = array1[1].split("=");
String timeInput = array3[1];
try {
eventClass = Class.forName(eventInput);
timeDelay = Long.parseLong(timeInput);
try {
addEvent(new eventClass(timeDelay));
}
//catch block
catch(NoSuchMethodException e){
System.out.println("No Such Method Error");
} catch (Exception e) {
System.out.println("error");
}
//catch block
} catch (ClassNotFoundException ex) {
System.out.println("Unable to locate Class");
} catch (IllegalAccessException ex) {
System.out.println("Illegal Acces Exception");
} catch (InstantiationException ex) {
System.out.println("Instantiation Exception");
}
}
}
//Close bufferedReader
bufferedReader.close();
}
//catch block
catch (FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
file + "'");
} catch (IOException ex) {
ex.printStackTrace();
}
break;
}
//if input match is not found
else {
System.out.println("No Match Found");}
}
}
I seem to be able to parse fine, and find the strings i'm looking for, but I'm not able to use eventInput which I've pulled from the text file as a parameter to create a new event.
eventClass = Class.forName(eventInput);
doesn't seem to be turning my string into an acceptable parameter either.
Any help would be much appreciated!
I know I'm probably missing something key here, but I've been staring at it too long that it seems like a lost cause.
Here is the Event class:
public abstract class Event {
private long eventTime;
protected final long delayTime;
public Event(long delayTime) {
this.delayTime = delayTime;
start();
}
public void start() { // Allows restarting
eventTime = System.currentTimeMillis() + delayTime;
}
public boolean ready() {
return System.currentTimeMillis() >= eventTime;
}
public abstract void action();
} ///:~
I think you've misunderstood how reflection works. Once you have a Class object (the output from Class.forName(), you have to find the appropriate constructor with
Constructor<T> constructor = eventClass.getConstructor(parameter types)
and then create a new instance with
constructor.newInstance(parameters);
For a no-arg constructor there's a shortcut
eventClass.newInstance();
I strongly suggest you read the tutorials on reflection before proceeding.

Close a BufferedReader in a Iterator for returning file lines

I wrote the following class for an iterator that iterates along the lines of a file.
import java.io.*;
import java.util.Iterator;
public class FileIterator implements Iterator<String> {
private BufferedReader reader;
public FileIterator(String filename) {
this.reader = getBufferedReader(filename);
}
private static BufferedReader getBufferedReader(String filename) {
File file = new File(filename);
if(file.exists()) {
try {
return new BufferedReader(new InputStreamReader(
new FileInputStream(new File(filename)),"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
System.out.println(filename + " is not there");
return null;
}
}
public boolean hasNext() {
try {
return reader.ready();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public String next() {
try {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void remove() {}
}
Now my question is a bit naive. Will be the reader closed once the iterator is no more used, when the GC will take care of it? Would the class improve if I close the reader manually? Maybe as a side effect in the hasNext() method:
public boolean hasNext() {
try {
if(reader.ready()) return true;
else {
reader.close();
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
Thanks!
If you really want to do this, I would have FileIterator implement Closeable and delegate the call to the underlying BufferedReader. You could even use it in a Java 7 try-with-resources block.

Categories

Resources