Differentiating between reading a file, and user input in a method - java

This program starts off in the FleetInterface class by asking the user for a file (run()). The buildFleet() method reads the file then calls the Vehicle to the Fleet class by calling the addVehicle() method and in that method, it sets the new Vehicle object into the vehicle array.
After all that's done, a user menu comes up asking if they would like to 1.) Add a Vehicle, 2.) Delete a Vehicle.
Let's say they add a new Vehicle. The requirement is to have the user manually enter data about that vehicle (All the same info that was in the file in the beginning). The problem is that this option also calls addVehicle(). If I program in the addVehicle() method some statements like "Please enter the model of your vehicle:", that will also show up when the program first starts and calls addVehicle().
The tricky part - I am not allowed to create any new public methods (only private), and I cannot add any new class level data.
My Fleet class has 2 constructors: 1 is blank (Not allowed to set anything here.) And 1 has a parameter value of File (Used for reading the original file).
So to sum it up, I need a way for the program to start by reading the values in a file, calling addVehicle(), then also allow the user to enter in a vehicle manually via Scanner.. while also calling addVehicle()
Here is my code:
FleetInterfaceApp:
public void run() throws FileNotFoundException
{
File file = new File(getFile());
fleet = new Fleet(file);
buildFleet(file);
}
private void buildFleet(File file) throws FileNotFoundException
{
fleet = new Fleet(file);
fleet.addVehicle(Honda);
userMenu(file, fleet);
}
private void userMenu(File file, Fleet fleet) throws FileNotFoundException
{
int choice = 0;
Scanner input = new Scanner(System.in);
this.createMenu();
choice = this.menu.getChoice();
switch(choice)
{
case 1:
fleet.addVehicle(Honda);
break;
}
}
Fleet:
Class Level data (cannot change):
Vehicle[] vehicles = new Vehicle[4];
File file;
addVehicle:
public void addVehicle(Vehicle Honda[]) throws FileNotFoundException
{
Scanner reader = new Scanner(file);
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length; i++)
{
if(vehicles[i] == null)
{
Honda[i] = new Vehicle();
Honda[i].readRecord(reader);
vehicles[i] = Honda[i];
reader.close();
break;
}
}
System.out.println("Vehicle Added!");
}
else
{
System.out.println("You can not add more than 4 vehicles.");
}
}

You can write out the user input to a temp file and then set the file attribute in your fleet object to the temp file before you call addVehicle. The file attribute is accessible to other classes because it is scoped package private by default. This means that any classes in the same package can access it. If FleetInterfaceApp is in the same package then it can already do this.
Here is some example code based off of the code provided in the question. This needs extra work before it will run.
// somewhere inside userMenu(File file, Fleet fleet)
File tempFile = File.createTempFile( "tmp", ".tmp" );
FileWriter fout = new FileWriter( tempFile );
fout.append( userInput );
fout.close();
fleet.file = tempFile;
switch(choice)
{
case 1:
fleet.addVehicle(Honda);
break;
}

Related

Java: ClassNotFound Classpath issues

Im trying to read some information from a file into some objects. Main method just reads the Information into some string variables then uses those strings to initialize objects. Pretty simple. The objects are stored using a BST.
However, The error Im getting is ClassNotFoundException. Except when I run the java 'file' command, 'file' is spelled and capitalized correctly.
I've been reading that you can change the path that JVM uses when searching for class files.
so I tried:
set CLASSPATH=$CLASSPATH=~/../../BackEnd
but that didn't do anything..
Here is my main file..
import java.util.Scanner;
import java.io.File;
class BackEnd
{
public static void main(String args[]) throws java.io.FileNotFoundException
{
Tree.ServiceTree providers = new Tree.ServiceTree();
String path = "./providers.txt";
Scanner read = new Scanner (new File(path));
read.useDelimiter(",");
String information[] = new String[5];//array of strings used to store info from file, then used to initialize objects
try
{
while(read.hasNext())
{
for(int i = 0; i < 5; ++i)
{
information[i] = read.nextLine();//read in all the info into the array
}
Services.Service newService;//used as dynamic reference to be passed to tree
Services.Service serviceInfo = new Services.Service(information[0], information[1]);//initalizes base class to be passed to derived constructor
switch(information[0])//check type to initalize appropriate object
{
case "Dogwalk":
newService = new Services.Dogwalk(serviceInfo, information[2], information[3]);
case "Groceries":
newService = new Services.Groceries(serviceInfo, information[2], information[3]);
case "Housework":
newService = new Services.Housework(serviceInfo, information[2], information[3]);
}
providers.insert(information[4], newService);
}
read.close();
throw new java.io.FileNotFoundException("File not found...");
}
catch(java.io.FileNotFoundException exception)
{
System.out.println("File not found");
}
//providers.display();
}
}
Figured it out. Error had nothing to do with compilation or class path and was due
to uninitialized variable newService

Implementing my Java Program in Talend : can't Drag & Drop

Here's the deal :
I was asked to developp a JAVA program that would do some reorganisations of .tsv files (moving cells to do some kind of transposition).
So, I tried to do it cleanly and got now 3 different packages:
.
Only tsvExceptions and tsvTranspositer are needed to make the main (TSVTransposer.java) work.
Yesterday I learned that I would have to implement it in Talend myself which I had never heard of.
So by searching, i stepped on this stackOverflow topic. So i followed the steps, creating a routine, copy/pasting my main inside it (changing the package to "routines") and added the external needed libraries to it (my two packages exported as jar files and openCSV). Now, when I open the routine, no error is showned but I can't drag & drop it to my created job !
Nothing happens. It just opens the component infos as shown with "Properties not available."
package routines;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import tsvExceptions.ArgsExceptions;
import tsvExceptions.EmptyArgsException;
import tsvExceptions.OutOfBordersArgsException;
import tsvTranspositer.CommonLine;
import tsvTranspositer.HeadOfValuesHandler;
import tsvTranspositer.InputFile;
import tsvTranspositer.OutputFile;
public class tsvRoutine {
public static void main(String[] args) throws ArgsExceptions {
// Boolean set to true while everything is good
Boolean everythingOk = true;
String inputFile = null; // Name of the entry file to be transposed.
String outputFile = null; // Name of the output file.
int serieNb = 1 ; // Number of columns before the actual values in the input file. Can be columns describing the product as well as empty columns before the values.
int linesToCopy = 0; // Number of lines composing the header of the file (those lines will be copy/pasted in the output)
/*
* Handling the arguments first.
*/
try {
switch (args.length) {
case 0:
throw new EmptyArgsException();
case 1:
inputFile = args[0];
String[] parts = inputFile.split("\\.");
// If no outPutFile name is given, will add "Transposed" to the inputFile Name
outputFile = parts[0] + "Transposed." + parts[1];
break;
case 2:
inputFile = args[0];
outputFile = args[1];
break;
case 3:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
break;
case 4:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
linesToCopy = Integer.parseInt(args[3]);
break;
default:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
linesToCopy = Integer.parseInt(args[3]);
throw new OutOfBordersArgsException();
}
}
catch (ArgsExceptions a) {
a.notOk(everythingOk);
}
catch (NumberFormatException n) {
System.out.println("Arguments 3 & 4 should be numbers."
+ " Number 3 is the Number of columns before the actual values in the input file. \n"
+ "(Can be columns describing the product as well as empty columns before the values. (1 by default)) \n"
+ "Number 4 is the number of lines to copy/pasta. (0 by default) \n"
+ "Please try again.");
everythingOk = false;
}
// Creating an InputFile and an OutputFile
InputFile ex1 = new InputFile(inputFile, linesToCopy);
OutputFile ex2 = new OutputFile(outputFile);
if (everythingOk) {
try ( FileReader fr = new FileReader(inputFile);
CSVReader reader = new CSVReader(fr, '\t', '\'', 0);
FileWriter fw = new FileWriter(outputFile);
CSVWriter writer = new CSVWriter(fw, '\t', CSVWriter.NO_QUOTE_CHARACTER))
{
ex1.setReader(reader);
ex2.setWriter(writer);
// Reading the header of the file
ex1.readHead();
// Writing the header of the file (copy/pasta)
ex2.write(ex1.getHeadFile());
// Handling the line containing the columns names
HeadOfValuesHandler handler = new HeadOfValuesHandler(ex1.readLine(), serieNb);
ex2.writeLine(handler.createOutputHOV());
// Each lien will be read and written (in multiple lines) one after the other.
String[] row;
CommonLine cl1;
// If the period is monthly
if (handler.isMonthly()) {
while (!ex1.isAllDone()) {
row = ex1.readLine();
if (!ex1.isAllDone()) {
cl1 = new CommonLine(row, handler.getYears(), handler.getMonths(), serieNb);
ex2.write(cl1.exportOutputLines());
}
}
}
// If the period is yearly
else {
while (!ex1.isAllDone()) {
row = ex1.readLine();
if (!ex1.isAllDone()) {
cl1 = new CommonLine(row, handler.getYears(), serieNb);
ex2.write(cl1.exportOutputLines());
}
}
}
}
catch (FileNotFoundException f) {
System.out.println(inputFile + " can't be found. Cancelling...");
}
catch (IOException e) {
System.out.println("Unknown exception raised.");
e.printStackTrace();
}
}
}
}
I know the exceptions aren't correctly handled yet, but they are in some kind of hurry for it to work in some way.
Another problem that will occur later is that I have no idea how to parse arguments to the program that are required.
Anyway, thanks for reading this post!
You cannot add routines per drag and drop to a job. You will need to access the routines functions through components.
For example, you would start with a tFileListInput to get all files you need. Then you could add a tFileInputDelimited where you describe all fields of your input. After this, with e.g. a tJavaRow component, you can write some code which would access your routine.
NOTE: Keep in mind that Talend works usually row-wise. This means that your routines should handle stuff in a row-wise manner. This could also mean that your code has to be refactored accordingly. A main function won't work, this has at least to become a class which can be instanciated or has static functions.
If you want to handle everything on your own, instead of a tJavaRow component you might use a tJava component which adds more flexibility.
Still, it won't be as easy as simply adding the routine and everything will work.
In fact, the whole code can become a job on its own. Talend generates the whole Java code for you:
The parameters can become Context variables.
The check if numbers are numbers could be done several ways, for example with a tPreJob and a tJava
Input file could be connected with a tFileInputDelimited with a dot separator
Then, every row will be processed with either a tJavaRow with your custom code or with a tMap if its not too complex.
Afterwards, you can write the file with a tFileOutputDelimited component
Everything will get connected via right click / main to iterate over the rows
All exception handling is done by Talend. If you want to react to exceptions, you can use a component like tLogRow.
Hope this helps a bit to set the direction.

how can i write in particular location of a text file in java

The Problem is that i have four different array lists . And I want to insert the data of particular array list class depending on the input given by user.
How can i do that ??
import java.io.*;
import java.util.*;
public class acquaintances
{
public static void main(String args[])
{
Arraylist<relative>re=new Arraylisrt<relative>();
Arraylist<personalfriend> pf=new Arraylist<personalfriend>();
Arraylist<casualfriend> cf=new Arraylist<casualfriend>();
Arraylist<professionalfriend> prf=new Arraylist<professionalfriend>():
These are different arraylists .
Iwant to write different acquantances info in the order in the text file
casual friend 1
casual friend2
........
relative 1
relative 2
......
personalfriend1
personal friend2
personal friend3
...........
professionalfriend1
professionalfriend2
..................
Also if i delete particular detail . then how am i supposed to erase particular
detail from the file
String name=null,number=null,email=null;
File file = new File("Readme.txt");
if (!file.exists()) {
file.createNewFile();
}
Scanner sc=new Scanner(System.in);
int ch=0,chu=0;
String jaff=null,baff=null;
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
String cmet_why=null,cinfo=null,cdate=null;
while(1)
{
System.out.println("Enter name,number,email of acquaintance");
name=sc.nextLine();
number=sc.nextLine();
email=sc.nextLine();
System.out.println("1.Create 2.Delete 3.Display 4. DisplayAll 5.Search );
ch=sc.nextInt();
jaff=sc.nextLine();
Switch(ch):
{
case 1:
{
System.out.println("1.Casual friend 2.relative 3.personal friend 4. Professional friend");
chu=sc.nextInt();
baff=sc.nextLine();
if(chu==1)
{
System.out.println("Enter reasonto meet ,dateof meeting,info");
cmet_why=sc.nextLine();
cdate=sc.nextLine();
cinfo=sc.nextLine();
casualfriend cfriend=new casualfriend(name,number,email,cmet_why,cdate,cinfo);
here i added the class object to the casual friend list
and i want to write it to text file in the location.
the problem is that it is in the middle of the text file.
After this i have to write relatives,personal friends ,professional friends .
info line by line
cf.add(cfriend);
}
}
}
}
}
}
there are different switch cases. i want to write these in the order.
public static void writeWithRandmoAccessFile( String content, String filePath) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(new File(filePath), "rw")) {
// move the cursor to the end of the file
// you can move the cursor to any position inside the file or to write at random positions
randomAccessFile.seek(randomAccessFile.length());//random position
randomAccessFile.write(content.getBytes());
// alternatively you can use randomAccessFile.writeChars(content)
// or randomAccessFile.writeUTF(content);
} catch (IOException e) {
e.printStackTrace();
}
}

saving random numbers in java

I'm doing an animation in Processing. I'm using random points and I need to execute the code twice for stereo vision.
I have lots of random variables in my code, so I should save it somewhere for the second run or re-generate the SAME string of "random" numbers any time I run the program. (as said here: http://www.coderanch.com/t/372076/java/java/save-random-numbers)
Is this approach possible? How? If I save the numbers in a txt file and then read it, will my program run slower? What's the best way to do this?
Thanks.
If you just need to be able to generate the same sequence for a limited time, seeding the random number generator with the same value to generate the same sequence is most likely the easiest and fastest way to go. Just make sure that any parallel threads always request their pseudo random numbers in the same sequence, or you'll be in trouble.
Note though that there afaik is nothing guaranteeing the same sequence if you update your Java VM or even run a patch, so if you want long time storage for your sequence, or want to be able to use it outside of your Java program, you need to save it to a file.
Here is a sample example:
public static void writeRandomDoublesToFile(String filePath, int numbersCount) throws IOException
{
FileOutputStream fos = new FileOutputStream(new File(filePath));
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(numbersCount);
for(int i = 0; i < numbersCount; i++) dos.writeDouble(Math.random());
}
public static double[] readRandomDoublesFromFile(String filePath) throws IOException
{
FileInputStream fis = new FileInputStream(new File(filePath));
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int numbersCount = dis.readInt();
double[] result = new double[numbersCount];
for(int i = 0; i < numbersCount; i++) result[i] = dis.readDouble();
return result;
}
Well, there's a couple of ways that you can approach this problem. One of them would be to save the random variables as input into a file and pass that file name as a parameter to your program.
And you could do that in one of two ways, the first of which would be to use the args[] parameter:
import java.io.*;
import java.util.*;
public class bla {
public static void main(String[] args) {
// You'd need to put some verification code here to make
// sure that input was actually sent to the program.
Scanner in = new Scanner(new File(args[1]));
while(in.hasNextLine()) {
System.out.println(in.nextLine());
}
} }
Another way would be to use Scanner and read from the console input. It's all the same code as above, but instead of Scanner in = new Scanner(new File(args[1])); and all the verification code above that. You'd substitute Scanner in = new Scanner(System.in), but that's just to load the file.
The process of generating those points could be done in the following manner:
import java.util.*;
import java.io.*;
public class generator {
public static void main(String[] args) {
// You'd get some user input (or not) here
// that would ask for the file to save to,
// and that can be done by either using the
// scanner class like the input example above,
// or by using args, but in this case we'll
// just say:
String fileName = "somefile.txt";
FileWriter fstream = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fstream);
out.write("Stuff");
out.close();
}
}
Both of those solutions are simple ways to read and write to and from a file in Java. However, if you deploy either of those solutions, you're still left with some kind of parsing of the data.
If it were me, I'd go for object serialization, and store a binary copy of the data structure I've already generated to disk rather than having to parse and reparse that information in an inefficient way. (Using text files, usually, takes up more disk space.)
And here's how you would do that (Here, I'm going to reuse code that has already been written, and comment on it along the way) Source
You declare some wrapper class that holds data (you don't always have to do this, by the way.)
public class Employee implements java.io.Serializable
{
public String name;
public String address;
public int transient SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}
And then, to serialize:
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("employee.ser");
ObjectOutputStream out =
new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
}
}
And then, to deserialize:
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn =
new FileInputStream("employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println(.Employee class not found.);
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Another alternative solution to your problem, that does not involve storing data, is to create a lazy generator for whatever function that provides you your random values, and provide the same seed each and every time. That way, you don't have to store any data at all.
However, that still is quite a bit slower (I think) than serializing the object to disk and loading it back up again. (Of course, that's a really subjective statement, but I'm not going to enumerate cases where that is not true). The advantage of doing that is so that it doesn't require any kind of storage at all.
Another way, that you may have not possibly thought of, is to create a wrapper around your generator function that memoizes the output -- meaning that data that has already been generated before will be retrieved from memory and will not have to be generated again if the same inputs are true. You can see some resources on that here: Memoization source
The idea behind memoizing your function calls is that you save time without persisting to disk. This is ideal if the same values are generated over and over and over again. Of course, for a set of random points, this isn't going to work very well if every point is unique, but keep that in the back of your mind.
The really interesting part comes when considering the ways that all the previous strategies I've described in this post can be combined together.
It'd be interesting to setup a Memoizer class, like described in the second page of 2 and then implement java.io.Serialization in that class. After that, you can add methods save(String fileName) and load(String fileName) in the memoizer class that make serialization and deserialization easier, so you can persist the cache used to memoize the function. Very useful.
Anyway, enough is enough. In short, just use the same seed value, and generate the same point pairs on the fly.

Output/Input of Java Files via GUI

I have three classes libraryDB, libraryItems and libraryGUI. libraryDB() is essentially a hash map with the keys as book barcodes/ISBN's and the values are libraryItems, which consist of and therefore take two String parameters: Title and Author.
I have a JFileChooser all set up in the GUI to save, but my save() and open() methods are giving problems. I want it set up so that when it is saved each libraryDB object has its own 3 lines (one each for Barcode, Title, Author, respectively). I tried loading them back in by reading each individual line in, here is the code I wrote for that:
//Suppose to construct a LibraryDB by reading one from a previously-saved file.
public LibraryDB (File file) throws IOException {
Scanner readFile = new Scanner(file);
int barcode;
String title;
String author;
while (readFile.hasNext()){
barcode = Integer.parseInt(readFile.nextLine());
title = readFile.nextLine();
author = readFile.nextLine();
LibraryItem authorTitleValues = new LibraryItem(title,author);
this.libraryItems.put(barcode, authorTitleValues);
}
}
//Trying to save to text file, where for each object n there are 3n lines.
public void save(File file) throws IOException {
PrintStream writer = new PrintStream(file);
for (Iterator<Integer> localIterator = libraryItems.keySet().iterator();
localIterator.hasNext();){
int barcode = ((Integer)localIterator.next()).intValue();
writer.println(barcode);
writer.println((libraryItems.get(Integer.valueOf(barcode))).getTitle());
writer.println((libraryItems.get(Integer.valueOf(barcode))).getAuthor());
}
}
Any help or insight that you can provide that will aid me in successfully being able to save/open would be much appreciated! Thanks!
More explicity, whenever I save a libraryDB to a file I am unable to go back later and open up the file?
You should flush() and close() your PrintStream before ending the save function. I'm not sure that is the problem, since your description is not too accurate, but do it anyway.
File streams and writer have to be explicitly closed at the end of writing to them - otherwise they will lock the file.
public void save(File file) throws IOException {
PrintStream writer = new PrintStream(file);
try {
for (Iterator<Integer> localIterator = libraryItems.keySet().iterator(); localIterator.hasNext();) {
int barcode = ((Integer) localIterator.next()).intValue();
writer.println(barcode);
writer.println((libraryItems.get(Integer.valueOf(barcode))).getTitle());
writer.println((libraryItems.get(Integer.valueOf(barcode))).getAuthor());
}
writer.flush();
} finally {
writer.close();
}
}
So, I just forgot to redeclare libraryDB!? Grrr...lol I don't think the compiler will complain because it has already been declared. However, the information being read from the file was just going into oblivion or something because there was no object for it to be put into. At least, that is what I think was happening. Thanks for your help. Here is my solution:
public LibraryDB (File file) throws IOException {
//this next line was what I was missing...sigh.
this.libraryItems = new HashMap<Integer, LibraryItem>();
Scanner readFile = new Scanner(file);
int barcode;
String title;
String author;
while (readFile.hasNext()){
barcode = Integer.parseInt(readFile.nextLine());
title = readFile.nextLine();
author = readFile.nextLine();
LibraryItem authorTitleValues = new LibraryItem(title, author);
libraryItems.put(Integer.valueOf(barcode), authorTitleValues);
}
readFile.close();
}

Categories