Operations on file with multithreading - java

I'm trying to work with multiThreading and I want to write a code that must do some operations on a specific file called data.txt.
There must be three writers and three readers,writer 1 has to write a random char from A to Z,writer 2 has to write a random number from 1 to 100,writer 3 has to write a random char from this set of characters {*%$##!&}.
Then readers must read a character from the file data.txt and then reader 1 write this character in file 1.txt,reader 2 write this character in file 2.txt and reader 3 write this character in file 3.txt.
If there was no character in data file to read the readers must wait until the writers add something to the data file.
I have wrote two classes called WriterInFile and ReaderFromFile that extends Thread class but it seems that the ReaderFromFile doesn't work correctly(It doesn't read any characters from data file and doesn't add anything to files 1.txt,2.txt,3.txt)
This is the code for ReaderFromFile class:
import java.io.*;
public class ReaderFromFile extends Thread {
private static FileReader reader;
private int numberOfReader;
ReaderFromFile(int numberOfReader, FileReader reader) {
this.numberOfReader = numberOfReader;
ReaderFromFile.reader = reader;
}
public void run() {
for (int i = 0; i < 5; i++) {
String s = null;
try {
s = readFrom();
} catch (IOException e) {
e.printStackTrace();
}
FileWriter writer;
switch (numberOfReader) {
case 1:
try {
writer = new FileWriter("1.txt",true);
if (s != null) {
writer.write(s);
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case 2:
try {
writer = new FileWriter("2.txt",true);
if (s != null) {
writer.write(s);
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case 3:
try {
writer = new FileWriter("3.txt",true);
if (s != null) {
writer.write(s);
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/**
* #return the character that has been reed
*/
private synchronized String readFrom() throws IOException {
String s = null;
while (!reader.ready()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
s = String.valueOf(reader.read());
} catch (IOException e) {
e.printStackTrace();
}
notifyAll();
return s;
}
}
this is the WriterInFile class:
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
public class WriterInFile extends Thread {
private static FileWriter writer;
private int numberOfReader;
WriterInFile(int numberOfReader, FileWriter writer) {
this.numberOfReader = numberOfReader;
WriterInFile.writer = writer;
}
public void run() {
for (int i=0;i<5;i++){
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch (numberOfReader) {
case 1:
writeChar();
break;
case 2:
writeNumber();
break;
case 3:
writeShape();
break;
}
}
}
private synchronized void writeChar() {
String s = getRandomChar();
try {
writer.write(s);
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
notifyAll();
}
private synchronized void writeNumber() {
String s = getRandomNumber();
try {
writer.write(s);
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
notifyAll();
}
private synchronized void writeShape() {
String s = getRandomShape();
try {
writer.write(s);
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
notifyAll();
}
private String getRandomChar() {
double randomDouble = Math.random();
randomDouble = randomDouble * 26;
int randomInt = (int) randomDouble;
return String.valueOf((char)(randomInt+'A'));
}
private String getRandomNumber() {
double randomDouble = Math.random();
randomDouble = randomDouble * 100 + 1;
int randomInt = (int) randomDouble;
return String.valueOf(randomInt);
}
private String getRandomShape() {
String chars = "*%$##!&";
Random rnd = new Random();
char randomChar = chars.charAt(rnd.nextInt(chars.length()));
return String.valueOf(randomChar);
}
}
and this is the main file:
public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("data.txt");
FileReader reader = new FileReader("data.txt");
//creating writers
WriterInFile writer1 = new WriterInFile(1, writer);
WriterInFile writer2 = new WriterInFile(2, writer);
WriterInFile writer3 = new WriterInFile(3, writer);
// creating readers
ReaderFromFile reader1 = new ReaderFromFile(1, reader);
ReaderFromFile reader2 = new ReaderFromFile(2, reader);
ReaderFromFile reader3 = new ReaderFromFile(3, reader);
writer1.start();
writer2.start();
writer3.start();
reader1.start();
reader2.start();
reader3.start();
Thread.sleep(10000);
writer.close();
reader.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}

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());
}

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;
}

java.lang.NullPointerException Serialization

I can't work out what is causing this exception. It happens in the reRead() method.
I've tested it without reRead() method and everything else works fine.
public class SerFiles {
private ObjectInputStream in;
private ObjectOutputStream out;
private FileReader fr;
private FileWriter fw;
private BufferedReader br;
private BufferedWriter bw;
private StringTokenizer token;
private ArrayList<Product> prod = new ArrayList<Product>();
private String line = "c";
private Product proc;
private int a,b,d,e,f;
private String c;
public SerFiles(){ }
public void openFiles()
{
try
{
out = new ObjectOutputStream( new FileOutputStream( "prod.ser" ) );
fr = new FileReader("SalesDelim.txt");
br = new BufferedReader(fr);
System.out.println("OPEN SUCCESS");
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
public void readAndWrite()
{
try
{
line = br.readLine();
while(line != null)
{
if(line != null)
{
token = new StringTokenizer(line, "**");
a = Integer.parseInt(token.nextToken());
b = Integer.parseInt(token.nextToken());
c = token.nextToken();
d = Integer.parseInt(token.nextToken());
e = Integer.parseInt(token.nextToken());
f = Integer.parseInt(token.nextToken());
prod.add(new Product(a,c,e,f));
line = br.readLine();
}
}
for(int i = 0; i<prod.size(); i++)
{
out.writeObject(prod.get(i));
}
System.out.println("WRITE SUCCESS");
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
public void reRead()
{
try
{
in = new ObjectInputStream(new FileInputStream("prod.ser")); //////ERROR HAPPENS HERE
while(true)
{
proc = (Product)in.readObject();
System.out.println(proc.toString());
}
}
catch(EOFException ioe){
return;
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
public void closeFiles()
{
try
{
fr.close();
br.close();
out.close();
in.close();
System.out.println("CLOSE SUCCESS");
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
}
}
I've tested it without reRead() method and it worked fine.
Thank you
Try:
in = new ObjectInputStream(new FileInputStream("prod.ser"));
while (true)
{
proc = (Product)in.readObject();
System.out.println(proc); // change!!
if (proc == null) break; // quit the loop
}
So, the problem was that you were calling toString() on a null-pointer.

Program in java that reads data from a text file

date time kg
12/10/2013 00.00.01 1
13/11/2013 00.00.05 2
17/12/2013 00.00.90 5
21/12/2013 00.00.23 6
27/12/2013 00.00.43 9
I have these data in an txt file. I would like to make o program in java that would read these data. I ' ve written the code above but I have mistakes. Could someone help me? The data have space between each other.
import java.io*;
public class ReadTextfile{
public static void main (String[] args) {
File file = new File ("test.txt");
StringBuilder line = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader (new FileReader(file));
String text = null;
while ((text = reader.readLine()) !=null) {
line.append(text)
.append(System.getProperty ("line.separator"));
}
}
catch (IOException e) {
e.printStackTrace();
catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
if (reader !=null){
reader.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(line.toString());
}
}
boy you are only having some syntax problem
1 : replace
import java.io* with import java.io.*
2 : take care of your catch body being started and closed properly
try
{
// your code
}
catch(Exception e)
{
}
here is the working code , compare your program
import java.io.*;
public class ReadTextfile{
public static void main (String[] args)
{
File file = new File ("C:/Users/hussain.a/Desktop/test.txt");
StringBuilder line = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader (new FileReader(file));
String text = null;
while ((text = reader.readLine()) !=null) {
line.append(text)
.append(System.getProperty ("line.separator"));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
if (reader !=null){
reader.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
System.out.println(line.toString());
}
}
catch (FileNotFoundException e)
This is unreachable code, since above it you caught IOException.
Note that:
public class FileNotFoundException extends IOException
Your code won't compile. Remove this catch (You didn't even close it..)
Another thing, if this is not a type, you should replace java.io* with import java.io.*.
I would take the following approach:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ReadTextFile
{
public static void main(String[] args) throws FileNotFoundException
{
File file = new File("test.txt");
Scanner scanner = new Scanner(file);
List<Result> results = new ArrayList<Result>();
while(scanner.hasNextLine())
{
String currentLine = scanner.nextLine();
String [] resultArray = currentLine.split(" ");
results.add(new Result(resultArray[0], resultArray[1], resultArray[2]));
}
scanner.close();
}
private static class Result
{
private String date;
private String time;
private String kg;
public Result(String date, String time, String kg)
{
super();
this.date = date;
this.time = time;
this.kg = kg;
}
public String getDate()
{
return date;
}
public String getTime()
{
return time;
}
public String getKg()
{
return kg;
}
}
}
Now you can pull out any information that you want to from the list of results that you have.
So if you wanted to print everything, you could do the following:
for(Result singleResult : results)
{
System.out.println(singleResult.getDate() + " " + singleResult.getTime() + " " + singleResult.getKg());
}
You basically can do whatever you want to with the data. This approach would also allow you to transform the data into different types before you even create the Result object.

Deserialize multiple Java Objects

hello dear colleagues,
I have a Garden class in which I serialize and deserialize multiple Plant class objects. The serializing is working but the deserializing is not working if a want to assign it to calling variable in the mein static method.
public void searilizePlant(ArrayList<Plant> _plants) {
try {
FileOutputStream fileOut = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
for (int i = 0; i < _plants.size(); i++) {
out.writeObject(_plants.get(i));
}
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
deserializing code:
public ArrayList<Plant> desearilizePlant() {
ArrayList<Plant> plants = new ArrayList<Plant>();
Plant _plant = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Object object = in.readObject();
// _plant = (Plant) object;
// TODO: ITERATE OVER THE WHOLE STREAM
while (object != null) {
plants.add((Plant) object);
object = in.readObject();
}
in.close();
} catch (IOException i) {
return null;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
return null;
}
return plants;
}
My invoking code:
ArrayList<Plant> plants = new ArrayList<Plant>();
plants.add(plant1);
Garden garden = new Garden();
garden.searilizePlant(plants);
// THIS IS THE PROBLEM HERE
ArrayList<Plant> dp = new ArrayList<Plant>();
dp = garden.desearilizePlant();
edit
I got a null Pointer exception
The solution of #NilsH is working fine, thanks!
How about serializing the entire list instead? There's no need to serialize each individual object in a list.
public void searilizePlant(ArrayList<Plant> _plants) {
try {
FileOutputStream fileOut = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(_plants);
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
public List<Plant> deserializePlant() {
List<Plants> plants = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
plants = in.readObject();
in.close();
}
catch(Exception e) {}
return plants;
}
If that does not solve your problem, please post more details about your error.
It may not always be feasible to deserialize a whole list of objects (e.g., due to memory issues). In that case try:
ObjectInputStream in = new ObjectInputStream(new FileInputStream(
filename));
while (true) {
try {
MyObject o = (MyObject) in.readObject();
// Do something with the object
} catch (EOFException e) {
break;
}
}
in.close();
Or using the Java SE 7 try-with-resources statement:
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(
filename))) {
while (true) {
MyObject o = (MyObject) in.readObject();
// Do something with the object
}
} catch (EOFException e) {
return;
}
If you serialize it to an array linear list, you can cast it back to an array linear list when deserializing it -- all other methods failed for me:
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Program
{
public static void writeToFile(String fileName, Object obj, Boolean appendToFile) throws Exception
{
FileOutputStream fs = null;
ObjectOutputStream os = null;
try
{
fs = new FileOutputStream(fileName);
os = new ObjectOutputStream(fs);
//ObjectOutputStream.writeObject(object) inherently writes binary
os.writeObject(obj); //this does not use .toString() & if you did, the read in would fail
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
fs.close();
}
catch(Exception e)
{
//if this fails, it's probably open, so just do nothing
}
}
}
#SuppressWarnings("unchecked")
public static ArrayList<Person> readFromFile(String fileName)
{
FileInputStream fi = null;
ObjectInputStream os = null;
ArrayList<Person> peopleList = null;
try
{
fi = new FileInputStream(fileName);
os = new ObjectInputStream(fi);
peopleList = ((ArrayList<Person>)os.readObject());
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch(EOFException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
fi.close();
}
catch(Exception e)
{
//if this fails, it's probably open, so just do nothing
}
}
return peopleList;
}
public static void main(String[] args)
{
Person[] people = { new Person(1, 39, "Coleson"), new Person(2, 37, "May") };
ArrayList<Person> peopleList = new ArrayList<Person>(Arrays.asList(people));
System.out.println("Trying to write serializable object array: ");
for(Person p : people)
{
System.out.println(p);
}
System.out.println(" to binary file");
try
{
//writeToFile("output.bin", people, false); //serializes to file either way
writeToFile("output.bin", peopleList, false); //but only successfully read back in using single cast
} // peopleList = (ArrayList<Person>)os.readObject();
// Person[] people = (Person[])os.readObject(); did not work
// trying to read one at a time did not work either (not even the 1st object)
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("\r\n");
System.out.println("Trying to read object from file. ");
ArrayList<Person> foundPeople = null;
try
{
foundPeople = readFromFile("input.bin");
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (foundPeople == null)
{
System.out.println("got null, hummm...");
}
else
{
System.out.println("found: ");
for(int i = 0; i < foundPeople.size(); i++)
{
System.out.println(foundPeople.get(i));
}
//System.out.println(foundPeople); //implicitly calls .toString()
}
}
}

Categories

Resources