Java input/output stream for primitive values - java

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.

Related

NoSuchElementException Scanner not waiting

I am working on my first server project for school and I am receiving a NoSuchElementException when reaching the code below in my client. From my understanding, the way I have written it, the scanner should be waiting for the server to send back a string. Instead it seems to be jumping right to the exception. In the server code (second below) I have the output that is supposed to return all strings in an array. My goal is to have the client print all of the strings in the text area (status).
static void runClient() {
Socket client = null;
PrintWriter output = null;
Scanner input = null;
try {
client = new Socket("localhost", 5007);
input = new Scanner(client.getInputStream());
output = new PrintWriter(client.getOutputStream());
output.println(game);
output.println(numberOfPicks);
output.flush();
pStr("Data Sent");
while (true) {
pStr("Waiting for Server");
status.appendText(input.nextLine());
if (!input.hasNext())
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
try {
client.close();
} catch (Exception e) {
}
}
}
private static void pStr(String string) {
System.out.println(string);
}
}
PARTIAL SERVER CODE BELOW
public void run() {
PrintWriter output = null;
Scanner input = null;
try {
// Get input and output streams.]
input = new Scanner(connection.getInputStream());
output = new PrintWriter(connection.getOutputStream());
String game;
int quickPicks;
try {
game = input.nextLine();
quickPicks = Integer.parseInt(input.nextLine());
switch (game) {
case "PowerBall":
ansStr = new pickNumbers(game, quickPicks, 69, 26).getQuickPicks();
break;
case "MegaMillions":
ansStr = new pickNumbers(game, quickPicks, 70, 25).getQuickPicks();
break;
case "Lucky4Life":
ansStr = new pickNumbers(game, quickPicks, 48, 18).getQuickPicks();
break;
default:
throw new RuntimeException("Incorrect Game");
}
} catch (Exception e) {
output.println(e.getMessage());
}
for (int i = 0; i < ansStr.length; i++) {
output.println(ansStr[i]);
//output.flush();
}
} catch (Exception e) {
pStr(e.getMessage());
} finally {
try {
input.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
try {
connection.close();
} catch (Exception e) {
}
}
}
}
How about nesting status.appendText(input.nextLine()); in a test for hasNextLine e.g:
if(input.hasNextLine()){
status.appendText(input.nextLine());
}

Why i can't open second stream in 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(){});

Java read file with scanner

I have this code that have some methods for creating a file, adding data to the file and then read the file with scanner.
My problem is that I want it to run my three methods at once but it stops
at the method number two and does not read the file with readFile() method
createFile();
addResponses(file);
readFile(file);
I can not run these three together. It does not read the file. But if I take
the other methods away like this
//createFile();
//addResponses(file);
readFile(file);
Then the read file method works.
I hope you did understand my problem. Is there something wrong with my code?
import java.io.*;
import java.util.Formatter;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Main {
static Formatter f;
static String sträng = " ";
static BufferedWriter output;
static File file;
static int nummer = 1;
static int counter = 0;
static private StringBuffer strBuff;
static InputStream is;
static FileWriter fw;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws Exception {
createFile();
addResponses(file);
readFile(file);
}
public static int addResponse() {
if (nummer == 6) {
try {
output.close();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
System.exit(0);
}
sträng = JOptionPane.showInputDialog("Numbers 1-5 to number " + nummer");
try {
return Integer.parseInt(sträng);
} catch (NumberFormatException f) {
return 6;
}
}
public static File createFile() {
try {
file = new File("numbers.txt");
f = new Formatter(file);
f.close();
} catch (SecurityException se) {
System.err.println("You dont have write access to this file");
System.exit(1);
} catch (Exception ex) {
System.err.println("Error opening or creating file");
System.exit(1);
}
return file;
}
public static void readFile(File x) {
try {
x = new File("numbers.txt");
Scanner in = new Scanner(x);
while (in.hasNextLine()) {
System.out.println(in.nextLine());
}
in.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static void addResponses(File f) throws IOException {
try {
fw = new FileWriter(f, true);
output = new BufferedWriter(fw);
int x = addResponse();
if (nummer == 1) {
output.write(String.format("%s%10s\n", "Rating", " Frequency"));
}
while (x != -1) {
if (x > 0 && x < 6) {
output.write(String.format("%s%10s\n", nummer, sträng));
nummer++;
} else {
JOptionPane.showMessageDialog(null, "Input only numbers between 1-5");
}
x = addResponse();
}
output.close();
} catch (IOException io) {
JOptionPane.showMessageDialog(null, "Wrong");
}
}
}
after playing around with the code, I found out that in your addResponse() method , you have added System.exit(0); so baiscally program was terminating. I've change it to return -1 and it seems to be working.
by the way, this is a very bad coding practice, each method should do stuff seperately regarless of other method. in your case everything is so integerated that is very hard to root the problem. I recommend you looking at some coding convention.
this is how addResponse() method should be working:
public static File createFile() {
try {
file = new File("numbers.txt");
f = new Formatter(file);
f.close();
} catch (SecurityException se) {
System.err.println("You dont have write access to this file");
System.exit(1);
} catch (Exception ex) {
System.err.println("Error opening or creating file");
System.exit(1);
}
return file;
}

How to determine the type of primitive in a String representation?

I have a String representation of a primitive and my goal is to determine which primitive is it.
My function is as follows:
public Object getPrimitive(String primitiveAsString) {
.....
}
So for example I would like to return an integer in case the input is "223" but a double if the input is "223.1" or even "223.0"(!!). Moreover, I would like to separate between float and double and even between integer and "BigInteger".
I have tried a solution using NumberFormat and it didn't work for me....
Is there an elegant way to do so?
Thanks!
An idea is just trying to return each type in try-catch.
Code: (the error-checking may be less than ideal)
public static void main(String[] args)
{
System.out.println(getPrimitive("123")); // Byte
System.out.println(getPrimitive("1233")); // Short
System.out.println(getPrimitive("1233587")); // Integer
System.out.println(getPrimitive("123.2")); // Float
System.out.println(getPrimitive("123.999999")); // Double
System.out.println(getPrimitive("12399999999999999999999999")); // BigInteger
System.out.println(getPrimitive("123.999999999999999999999999")); // BigDecimal
}
static public Object getPrimitive(String string)
{
try { return Byte.valueOf(string); } catch (Exception e) { };
try { return Short.valueOf(string); } catch (Exception e) { };
try { return Integer.valueOf(string); } catch (Exception e) { };
try { return new BigInteger(string); } catch (Exception e) { };
try { if (string.matches(".{1,8}"))
return Float.valueOf(string); } catch (Exception e) { };
try { if (string.matches(".{1,17}"))
return Double.valueOf(string); } catch (Exception e) { };
try { return new BigDecimal(string); } catch (Exception e) { };
// more stuff ?
return null;
}
The reasoning behind .{1,8} and .{1,17} is that float and double are accurate to about 7 and 16 digits each (according to some random source). . is a wild-card. {x,y} means repeated between x and y times.
EDIT:
Improved to differentiate float, double and BigDecimal with a basic regex among other things.
I doubt you can do this very easily. It will be very tricky or almost impossible to detect if the contents of the String belongs to integer or BigInteger. You can of course distinguish between int and double/float by writing a regex to determine if it contains '.' and rest of the characters are numbers.
I would do something like this ... this should work for BigInteger and BigDecimal as well ... Haven't tested it though.
public Object getPrimitive(String primitiveAsString) {
String value = primitiveAsString;
try {
return Byte.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return Short.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return Integer.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return Float.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return Double.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return Long.valueOf(value);
} catch (NumberFormatException ex) { }
try {
return new BigInteger(value);
} catch (NumberFormatException ex) { }
try {
return new BigDecimal(value);
} catch (NumberFormatException ex) { }
if(value.length() == 1) {
return new Character(value.charAt(0));
}
return null;
}
EDIT: improved the solution to cater for cases when the input is a BigInteger/BigDecimal. This solution does not use any regex.

ObjectOutputStream, ObjectInputStream, and headers [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to understand object serialization better, so I am practicing with some code I got from my textbook. (My textbook doesn't explain how to read and write/append objects to a serialization file every time the program starts, which is what I need to do.) I took their program, which just overwrites existing data in a file with the objects from the current session, and add code to it so that it will append the objects and read the whole file instead. I found something really useful here: Appending to an ObjectOutputStream but even if I create a subclass of ObjectOutputStream, override the writeStreamHeader method, and call this subclass if the file already exists, which is what they did, it still throws a CorruptedStreamException. My guess is that I would need to set the pointer back to the beginning of the file, but that doesn't seem to be necessary as there is only one ObjectOutputStream. So, my question is, what else could I possibly need to do?
EDIT: Here is some code.
WriteData.java
import java.io.*;
import java.util.Scanner;
public class WriteData
{
private int number;
private String name;
private float money;
private ObjectInputStream testopen;
private ObjectOutputStream output; //This is for the output. Make sure that
//this object gets an instance of FileOutputStream so that it can write objects
//to a FILE.
private AppendObjectOutputStream appendobjects;
static Scanner input = new Scanner(System.in);
static DataClass d;
public void openfile()
{
//Try opening a file (it must have the ".ser" extension).
try
{
//output = new ObjectOutputStream(new FileOutputStream("test.ser"));
testopen = new ObjectInputStream(new FileInputStream("test.ser"));
}
//If there is a failure, throw the necessary error.
catch (IOException exception)
{
try
{
output = new ObjectOutputStream(new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} //end case createfile
if (testopen != null)
{
try
{
testopen.close();
appendobjects = new AppendObjectOutputStream(
new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void writedata()
{
//write the data until the user enters a sentry value.
System.out.println("Enter CTRL + z to stop input.\n");
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
while (input.hasNext())
{
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
try
{
number = input.nextInt();
name = input.next();
money = input.nextFloat();
//Make object with that data
d = new DataClass(number, name, money);
//write it to the file
if (output != null)
{
output.writeObject(d);
}
else if (appendobjects != null)
{
appendobjects.writeObject(d);
}
}
catch (IOException e)
{
System.out.println("Error writing to file.");
return;
}
}
System.out.println("\n");
} //end writedata
public void closefile()
{
try
{
if (output != null)
{
output.close();
}
else if (appendobjects != null)
{
appendobjects.close();
}
}
catch (IOException e)
{
System.out.println("Error closing file. Take precautions");
System.exit(1);
}
}
}
DataClass.java
import java.io.Serializable;
public class DataClass implements Serializable
{
private int someint;
private String somestring;
private float somefloat;
public DataClass(int number, String name, float amount)
{
setint(number);
setstring(name);
setfloat(amount);
}
public void setint(int i)
{
this.someint = i;
}
public int getint()
{
return someint;
}
public void setstring(String s)
{
this.somestring = s;
}
public String getstring()
{
return somestring;
}
public void setfloat(float d)
{
this.somefloat = d;
}
public float getfloat()
{
return somefloat;
}
}
AppendObjectOutputStream.java
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
public class AppendObjectOutputStream extends ObjectOutputStream
{
public AppendObjectOutputStream(FileOutputStream arg0) throws IOException
{
super(arg0);
// TODO Auto-generated constructor stub
}
//This is a function that is default in ObjectOutputStream. It just writes the
//header to the file, by default. Here, we are just going to reset the
//ObjectOutputStream
#Override
public void writeStreamHeader() throws IOException
{
reset();
}
}
ReadData.java
import java.io.*;
import java.util.Scanner;
public class ReadData
{
private FileInputStream f;
private ObjectInputStream input; //We should the constructor for this
//object an object of FileInputStream
private Scanner lines;
public void openfile()
{
try
{
f = new FileInputStream("test.ser");
input = new ObjectInputStream (f);
//input.reset();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
public void readdata()
{
DataClass d;
System.out.printf("%-15s%-12s%10s\n", "Account Number", "First Name",
"Balance");
try
{
while (true)
{
d = (DataClass)input.readObject(); //define d
//read data in from d
System.out.printf("%-15d%-12s%10.2f\n", d.getint(), d.getstring(),
d.getfloat());
}
}
catch (EOFException eof)
{
return;
}
catch (ClassNotFoundException e)
{
System.err.println("Unable to create object");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void closefile()
{
try
{
if (input != null)
{
input.close();
}
}
catch (IOException ex)
{
System.err.println("Error closing file.");
System.exit(1);
}
}
}
SerializationTest.java
public class SerializationTest
{
public static void main(String[] args)
{
ReadData r = new ReadData();
WriteData w = new WriteData();
w.openfile();
w.writedata();
w.closefile();
r.openfile();
r.readdata();
r.closefile();
}
}
I suggest to do it this way
ObjectOutputStream o1 = new ObjectOutputStream(new FileOutputStream("1"));
... write objects
o1.close();
ObjectOutputStream o2 = new AppendingObjectOutputStream(new FileOutputStream("1", true));
... append objects
o2.close();
it definitely works.
import EJP;
import Evgeniy_Dorofeev;
public class answer
{
private String answera, answerb;
public answer(String a, String b)
{
answera = a;
answerb = b;
}
public void main(String[] args)
{
answer(EJP.response(), Evgeniy_Dorofeev.response());
System.out.println(answera + '\n' + answerb);
}
}
You need to add a 'true' for the append parameter of new FileOutputStream() in the case where you are appending. Otherwise you aren't. Appending, that is.

Categories

Resources