Writing data to a txt file file using java classes - java

I am trying to understand why my code is not writing the output to the textfile as I expect it to work. My program takes a filename as a command line argument, and prints some text to the file as well as the screen. It is a bit more complicated since it uses classes and objects to demonstrate how objects work. Can anyone help decipher why it is not writing to the file? Here's my code:-
public class Mamoonp3test {
public static void main(String[] args) throws Exception {
//Create array of 10 guitar (Mamoonp3) objects
final int NUMBER_OF_INSTANCES = 10;
Mamoonp3[] objectNames = new Mamoonp3[NUMBER_OF_INSTANCES];
try
{
String fileName = new String(args[0]);
for(int i=0; i<NUMBER_OF_INSTANCES; i++) {
objectNames[i] = new Mamoonp3(FileName);
System.out.println("This is guitar number: " + i);
objectNames[i].tuneGuitar();
objectNames[i].playGuitar();
objectNames[i].displayAcronym();
objectNames[i].stopGuitar();
System.out.println("---------------------------");
}
}
catch (Exception e)
{
System.out.println("please provide an input file");
System.out.println("Usage: java Mamoonp3test filename.txt");
}
}
}
import java.io.*;
public class Mamoonp3 {
final int NUMBER_OF_STRINGS = 6;
char[] stringNames = {'E','A','D','G','B','E'};
int[] stringNumbers = {6,5,4,3,2,1};
String[] stringPitch = {"Sixth","Fifth","Fourth","Third","Second","First"};
boolean isTuned;
boolean isPlaying;
String stringAcronym = new String("Even After Dinner Giant Boys Eat");
//create a PrintWriter for output
PrintWriter output;
public Mamoonp3(String fileName) throws Exception{
isTuned = false;
isPlaying = false;
// create target file
File targetFile = new File(fileName);
//create a PrintWriter for output
output = new PrintWriter(targetFile);
}
public void tuneGuitar() {
System.out.println("The guitar is now tuned.");
for (int i=0; i<NUMBER_OF_STRINGS; i++) {
System.out.println(stringNames[i] + " is string number " + stringNumbers[i] + " and ranked " + stringPitch[i] + " in pitch");
output.print(stringNames[i] + " is string number " + stringNumbers[i] + " and ranked " + stringPitch[i] + " in pitch");
output.close();
}
}
public void playGuitar() {
System.out.println("The guitar is now playing.");
output.print("The guitar is now playing.");
output.close();
}
public void stopGuitar() {
System.out.println("The guitar is now stoped.");
output.print("The guitar is now stoped.");
output.close();
}
public void displayAcronym() {
System.out.println("Always remember your string names!");
System.out.println("Heres a reminder: " + stringAcronym);
output.print("Always remember your string names!");
output.print("Heres a reminder: " + stringAcronym);
output.close();
}
}

You're setting the File of an object that you then do nothing with, that you're not writing with,
Mamoonp3 newObject = new Mamoonp3(fileName);
... and not setting the File in objects that you try to write with. Check which constructors you are using: every Manoop3 object created in the for loop. To see that this is so, check which constructors you're using
I suggest that you change your approach entirely.
Get all file input and output out of your Mamoonp3 class.
Instead, that class should concern itself with representing the state of the musical instrument, and nothing else.
Give the class a decent toString() override method.
I & O should go elsewhere in a separate class of its own.
Give your I&O class a method that allows you to pass Mamoonp3 objects into it so that they can be written.
As an aside, you almost never would use new String(anything). Just use args[0].
Always close your PrintWriter when you are done writing. This is likely causing your error.
Edit
Possibly another way to solve this:
Create a PrintWriter object in the main method.
Give your Manoop3 class a PrintWriter field and a constructor that takes this PrintWriter and sets its field with it.
Write with the PrintWriter in Manoop3, but don't close it.
Then close the PrintWriter in the main method when all Manoop3 objects have completed their use of it.

Related

How to solve my try-catch exception handling?

I'm having problems with my try-catch exception here. Actually what it does is to prompt the user for the name of a text file say, Robot.txt but if say the file does not exist, I have to make sure that the application reprompts the user for the file name. Hope you guys can understand I'm still a newbie here so please feel free to provide suggestions or advices on my coding etc. Cheers!
Main method class:
import java.io.*;
import java.util.Scanner;
import java.util.Vector;
class TestVector3 {
public static void main(String [] args)
{
System.out.println("Please enter the name of the text file to read: ");
Scanner userInput = new Scanner(System.in);
Vector <KillerRobot> robotDetails = new Vector <KillerRobot>();
KillerRobot robot;
Scanner fileInput = null;
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :"); //Reprompt user for name of the text file
fileInput = new Scanner(userInput.nextLine());
}
while(fileInput.hasNext())
{
robot = new KillerRobot();
String first = fileInput.next();
robot.setName(first);
String second = fileInput.next();
robot.setMainWeapon(second);
int third = fileInput.nextInt();
robot.setNumberOfKills(third);
robotDetails.add(robot);
}
for(KillerRobot i : robotDetails)
{
System.out.println(i);
}
fileInput.close();
}
}
KillerRobot class file:
class KillerRobot {
private String name;
private String mainWeapon;
private int numberOfKills;
KillerRobot()
{
}
public String getName()
{
return name;
}
public String getMainWeapon()
{
return mainWeapon;
}
public int getNumberOfKills()
{
return numberOfKills;
}
public String toString()
{
return name + " used a " + mainWeapon + " to destroy " + numberOfKills + " enemies ";
}
public void setName(String a)
{
name = a;
}
public void setMainWeapon(String b)
{
mainWeapon = b;
}
public void setNumberOfKills(int c)
{
numberOfKills = c;
}
}
As you state that you are a beginner, let us first look at the relevant part of your code, to make sure that we talk about the same thing:
Scanner fileInput = null;
try {
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You have an input and you want to check this input for a condition and require a new input until this condition is fulfilled. This problem can be solved using a loop like the following:
Scanner fileInput = null;
do {
System.out.println("Enter file name :");
try {
fileInput = new Scanner(new File(userInput.nextLine()));
} catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
}
} while(fileInput == null);
So finally, why does this work? The fileInput variable is set to null and will remain null until the given file is successfully read from standard input because an exception is thrown otherwise what prevents the fileInput variable to be set. This procedure can be repeated endlessly.
On a side note, for performance reasons, it is normally not a good idea to implement control flow that is based on exceptions. It would be better to check for a condition if a file exists via File::exists. However, if you read the file after checking for its existence, it might have been deleted in the meantime which introduces a racing condition.
Answer to your comment: In Java (or almost any programming language), you can inline expressions. This means that instead of calling two methods in two different statements as in
Foo foo = method1();
Bar bar = method2(foo);
you can simply call
Bar bar = method2(method1());
This way, you save yourself some space (what becomes more and more important if your code gets longer) as you do not need the value that you saved in foo at any other place in your code. Similarly, you can inline (which is how this pattern is called) from
File file = new File(userInput.nextLine())
fileInput = new Scanner(file);
into
fileInput = new Scanner(new File(userInput.nextLine()));
as the file variable is only read when creating the Scanner.
Try putting the try-catch in a loop like below:
Scanner fileInput = null;
while (fileInput==null)
{
try
{
System.out.println("Please enter the file name.");
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
}
}
Next you could think of moving the File creation part into separate method, so that the code was cleaner.
Do not fall for try-catch instead add this as your functionality. Exceptions are naturally for run time error handling not for logic building.
Check if file exists at given location.
File textFile = new File(userInput.nextLine());
// Check if file is present and is not a directory
if(!textFile.exists() || textFile.isDirectory()) {
System.out.println("Error - file not found!");
//Reprompt user for name of the text file
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You can put while loop instead of if loop if you want to continuously prompt user until correct path is entered.
You can call back your main(), like following
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
main(args); // recursively call main() method
}
Now if user first attempt wrong then your code will asked to re enter file name.
How to check isFile exist?
File file = new File(filePathString);
if(file.exists() && !file.isDirectory()){
System.out.println("file exist");
}
This really is an XY problem because you assumed the only way to check for a file existence is by catching a FileNotFoundException (hence asking about try-catch exception handling) whereas other means exist to help you avoid a try-catch idiom in an elegant manner.
To check if a file exists at the given path or not you can simply use the File.exists method. Please also see the File.isFile method and/or the File.isDirectory method to verify the nature of the targeted File object.
EDIT : As stated by raphw, this solution is best used in simple scenario since it can incur a race condition in the case of concurrent file deletion happening during the file existence check. See his answer for handling more complex scenario.

Can not get java to write to a text file using PrintWriter

Let me preface this by saying that I'm extremely new to java. This is my eighth week in the class and I'm stuck on a project. Here is what I have so far:
import java.io.*;
public class Guitar {
// Initialize variables
boolean isPlaying;
boolean inTune;
char[] guitStrings = {'D', 'G', 'C', 'A'}; // Guitar strings
int numOfStrings = 4; // Number of strings the guitar has.
public void Guitar(){
isPlaying = false; // Guitar is not playing by default.
inTune = false; // Guitar is not tuned by default.
System.out.println("The guitar is not tuned and is not playing.");
}
public void isPlaying(){
System.out.println("Your guitar is now playing!");
isPlaying = true; // Set guitar to playing
}
public void inTune(){
System.out.println("Your guitar is now tuned!");
inTune = true; // Set guitar to tuned.
}
public void stopPlaying(){
isPlaying = false; // Set isPlaying to false.
System.out.println("Your guitar has finished playing!");
}
public void notes(){
System.out.println("The guitar has played a total of " + numOfStrings +
" strings and they are: " + guitStrings[0] + "," + guitStrings[1] + ","
+ guitStrings[2] + "," + guitStrings[3]);
}
public static void main(String[] args) throws IOException{
java.io.File file = new java.io.File("guitartest.txt");
if(file.exists()){
System.out.println("File already exists!");
System.exit(1);
}
// Create a file
java.io.PrintWriter output = new java.io.PrintWriter(file);
Guitar[] guit = new Guitar[10];
for (int i = 0; i < guit.length; i++){
guit[i] = new Guitar();
guit[i].Guitar();
guit[i].inTune();
guit[i].isPlaying();
guit[i].notes();
guit[i].stopPlaying();
}
}
}
This program does everything I need it to do, but we have one last step on the project. I must output this to a text file from the command line. I've changed the last bit of code to this:
public static void main(String[] args) throws IOException{
java.io.File file = new java.io.File("guitartest.txt");
if (file.exists()){
System.out.println("This file already exists!");
System.exit(1);
}
// Create a file
java.io.PrintWriter output = new java.io.PrintWriter(file);
Guitar[] guit = new Guitar[10]; // Create 10 instruments
for (int i = 0; i < guit.length; i++){
output.println(guit[i] = new Guitar());
output.println(guit[i].Guitar());
output.println(guit[i].inTune());
output.println(guit[i].isPlaying());
output.println(guit[i].notes());
output.println(guit[i].stopPlaying());
}
}
This compiles the codes, and displays the results I want in the console, but the text file guitartest.txt is completely blank. I am NOT looking for someone to complete this assignment for me, I'm just looking for any advice or resources you could point me to. Thank you very much!
PrintWriter is buffered, that means that the text you're writing to it is stored in its internal buffer before being actually written to the file. So you need to call a close() method when you're done writing, so that the PrintWriter object wrote the data to the file and closed it.
You can also call flush(), this may be useful if you want your data written now but also want to continue using the PrintWriter object.
After you're done writing
output.flush();
output.close();
The PrintWriter constructor that accepts a File is implemented as
public PrintWriter(File file) throws FileNotFoundException {
this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
false);
}
In other words, your outputs are being buffered and need to be flushed from time to time or all in one shot.
Call
output.flush();
or
output.close();
when you are finished using it.
You probably need to flush the output stream at the end, i.e. after the for loop in the main() method do
output.flush();
output.close();
You can include both of these calls in a try/catch block, for safety:
try {
output.flush();
output.close();
} catch (Exception e) {
e.printStackTrace();
}

Can't Write to File

I need some help please writing the output to a file and I can't get it to work. If I use the System.out.println it works. If I create the file stream and Buffered Writer in the actual method, it creates the file but doesn't write anything to it. I'm assuming it's because my method is recursive and creates a new file every time the method calls it self again. So I created another print method and used the string value key[i] as the string parameter and it does nothing.
Any help is appreciated, thank you.
public void print(String s)throws IOException
{
fstream = new FileWriter("out.txt", true);
out = new BufferedWriter(fstream);
try{
out.write("From print: " + s + " ");
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
public void generate() throws IOException
{
while (k<randomWordNum())
{
if (randomNum() <= sumOfFreq[0])
{
//System.out.println(getKey[0] + " ");
print(getKey[i]);
i++;
k++;
generate();
}
if (randomNum() >= sumOfFreq[i] && randomNum() <= sumOfFreq[i+1])
{
//System.out.println("From generate: " + getKey[i+1] + " ");
print(getKey[i+1]);
i++;
k++;
generate();
}
else
{
i++;
generate();
}
}//while
}//generate
You need to .close the file to make sure things get written
I think that constructor of FileWriter will overwrite the file. So you'll need to use a code line like this:
fstream = new FileWriter("out.txt", true); // true for appending
Also, always close a file before it goes out of scope, otherwise it might never get flushed or closed if you are unlucky...
And one more thing, assuming that is not some sort of debug/troubleshooting code, "never" catch Exception. If you do catch it, be sure to re-throw it asyou got it after logging or whatever you did with it. But, in general, always catch a more specific exception type.

How to call a class that accepts command line arguments?

I am not a good programmer. In school, I learned MATLAB. So i have no idea what I am doing.
I am working with the ThingMagic M6 reader. They have their own API. I wanted to create my own application to read the program. I want to use a sample program that they have supplied (since my program doesn't seem to work). However, the supplied program only accepts command line arguments. How do i change it so I can pass arguments to it in my code.
This is the supplied code: (at the command line I input tmr://10.0.0.101)
/**
* Sample program that reads tags for a fixed period of time (500ms)
* and prints the tags found.
*/
// Import the API
package samples;
import com.thingmagic.*;
public class read
{
static void usage()
{
System.out.printf("Usage: demo reader-uri <command> [args]\n" +
" (URI: 'tmr:///COM1' or 'tmr://astra-2100d3/' " +
"or 'tmr:///dev/ttyS0')\n\n" +
"Available commands:\n");
System.exit(1);
}
public static void setTrace(Reader r, String args[])
{
if (args[0].toLowerCase().equals("on"))
{
r.addTransportListener(r.simpleTransportListener);
}
}
static class TagReadListener implements ReadListener
{
public void tagRead(Reader r, TagReadData t) {
System.out.println("Tag Read " + t);
}
}
public static void main(String argv[])
{
System.out.println(argv.getClass().toString());
// Program setup
TagFilter target;
Reader r;
int nextarg;
boolean trace;
r = null;
target = null;
trace = false;
nextarg = 0;
if (argv.length < 1)
usage();
if (argv[nextarg].equals("-v"))
{
trace = true;
nextarg++;
System.out.println("Trace");
}
// Create Reader object, connecting to physical device
try
{
TagReadData[] tagReads;
r = Reader.create(argv[nextarg]);
if (trace)
{
setTrace(r, new String[] {"on"});
}
r.connect();
if (Reader.Region.UNSPEC == (Reader.Region)r.paramGet("/reader/region/id"))
{
r.paramSet("/reader/region/id", Reader.Region.NA);
}
r.addReadListener(new TagReadListener() );
// Read tags
tagReads = r.read(500);
// Print tag reads
for (TagReadData tr : tagReads)
System.out.println(tr.toString());
// Shut down reader
r.destroy();
}
catch (ReaderException re)
{
System.out.println("Reader Exception : " + re.getMessage());
}
catch (Exception re)
{
System.out.println("Exception : " + re.getMessage());
}
}
}
This is me trying to use it: (arg comes from a JTextField)
String[] argv = new String[1];
argv[0] = arg;
readOnceApp(argv);
I have a feeling there is a really simple answer to this problem, I just can't figure it out. I searched the internet for a few days and read books, and still can't figure it out. Any help is appreciated. Thank You.
edit: readOnceApp is one method I wrote. It is basically just the main method of the supplied code. I can include it, if it will help. I just didn't want to post too much code.
If you want to call the "main" method of a class from another class, do it like this:
String [] args = new String [1];
args[0]= "some param";
readOnceApp.main(args);
This is making the assumption that "readOnceApp" is the name of your class. (BTW, you should follow the convention of using capitalized class names, e.g. ReadOnceApp).
Hope this helps.

Help with line.split CSV

I'm a beginner, so please don't blast my work so far :)
I'm trying to read in a CSV file and then see if it matches certain commands. Some of the data in the CSV has a period and I think it's messing up when I'm trying to split it. When I try to dump my arrays to see what's there, it always gets cut off after the period. Here is a data sample. Any help would be appreciated. Again I'm a beginner so simplicity would be appreciated.
Sample data
create,Mr. Jones,blah,blah
create,Mrs. Smith,blah,blah
public class TestHarness {
public static void main(String[] args) throws IOException, FileNotFoundException {
Scanner input = new Scanner(new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));
String[] validCommands = { "create", "move", "useWeapon", "search", "heal" };
boolean proceed = false;
while (!proceed)
{
for (int i = 0; i < validCommands.length; i++)
{
String line = input.next();
String[] nline = line.split (",");
if (nline[0].equals("create"))
{
String soldierName = nline[1];
String soldierType = nline[2];
String weapon = nline[3];
Soldier aSoldier = new Soldier(soldierName,weapon);
System.out.println("Command: "+ nline[0] +","+ soldierName +","+ soldierType+","+ weapon);
if (soldierType.equals("enlisted"))
{
Soldier s = new Enlisted(soldierName,weapon);
System.out.println(s.toString());
}
else if (soldierType.equals("officer"))
{
Soldier s = new Officer(soldierName,weapon);
System.out.println(s.toString());
}
}
else if (nline[0].equals("useWeapon")) {
System.out.print("weapon " + nline[0] + "\n");
}
else if (nline[0].equals("move")) {
System.out.print("move " + nline[0] + "\n");
}
else if (nline[0].equals("search")) {
System.out.print("search " + nline[0] + "\n");
}
else if (nline[0].equals("heal")) {
System.out.print("heal " + nline[0] + "\n");
}
}
}
}
}
Calling Scanner.next will only return the next word (separated by whitespace).
You need to call nextLine to read entire lines at a time.
There are several open source CSV parers available for Java:
http://supercsv.sourceforge.net/
http://commons.apache.org/sandbox/csv/
That was a rather quick mistake, wasn't it?
This is not an answer to your question but a recommendation to use a hash.
First define an interface
public interface InputDance
{
public void dance(String[] input);
}
I recommend that your main routine should be
public static void main(String[] args)
throws IOException, FileNotFoundException{
Scanner input = new Scanner(
new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));
String line = input.nextLine();
String[] nline = line.split (",");
InputDance inputxn = inputActions.get(nline[0]);
if (inputxn!=null)
inputxn.dance(nline);
}
You would be using a hash to store all the actions outlined by the interface InputDance.
So that your input reading routine would be simplified to
retrieve action from hash of actions
using word0 of input as key.
execute that action
If you have only five types of soldiers, it would ok to place all your logic in one routine.
However, for more than 10 types of personnel, it would be cleaner to place the actions outside the routine.
If you are writing a computer game, or keeping personnel records on a military database, you would frequently encounter enhancement requests to include new personnel types or exceptions to the rule. Then your if-then-else-if chain would become increasingly longer and confusing. Especially when there are special requirements for soldiers dancing to a different tune. Or when your game canvas or personnel database needs to include non-battle units. But, of course, you still need to update the hash in the main class every time you have a new personnel type.
Notice that in my recommendation all your routine would do is to perform the dance(String[]) method. Any complication would be handled by the individual class implementing the dance.
Next define an implementing class
public class SoldierDance
implements InputDance
{
public void dance(String[] nline){
String soldierName = nline[1];
String soldierType = nline[2];
String weapon = nline[3];
System.out.println(
"Command: "+ nline[0] +","+ soldierName +","+ soldierType+","+ weapon);
Soldier s;
if (soldierType.equals("enlisted")){
s = new Enlisted(soldierName,weapon);
}
else if (soldierType.equals("officer")){
s = new Officer(soldierName,weapon);
}
else{
s = new Soldier(soldierName,weapon);
}
System.out.println(s.toString());
}
}
Then define your main class. Notice that the hash is a static instance.
Also, there is a placeholder dance so that when you have a new personnel type, but you don't know what to do with it yet, you just hash the new personnel type to this placeholder dance.
Notice, for example in the "useWeapon" hash key, that an interface can be implemented anonymously too
public class TestHarness
{
static public class PlaceHolderDance
implements InputDance
{
public void dance(String[] nline){
System.out.print("Action=" + nline[0] + "\n");
}
}
static public Hashtable<String, InputDance> inputActions;
// A static enclosure is to execute all the class definition once.
static {
inputActions = new Hashtable<String, InputDance>();
InputDance placeHolderAction = new PlaceHolderDance();
inputActions.put("create", new SoldierDance());
inputActions.put("move", placeHolderAction);
inputActions.put("search", placeHolderAction);
inputActions.put("heal", placeHolderAction);
// Can also anonymously implement an interface
inputActions.put("useWeapon",
new InputDance(){
public void dance(String[] nline){
System.out.print("weapon " + nline[0] + "\n");
}
}
);
}
// The static main method
public static void main(String[] args)
throws IOException, FileNotFoundException{
Scanner input = new Scanner(
new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));
String line = input.nextLine();
String[] nline = line.split (",");
InputDance inputxn = inputActions.get(nline[0]);
if (inputxn!=null)
inputxn.dance(nline);
}
}
And, if there is a one-one correspondence between a soldier class and its inputdance, you could even implement InputDance in the soldier class and provide the dance method.

Categories

Resources