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();
}
Related
So I start with a textfile; this textfile at the start contains a number 3 (amount of woningen) 3 Woningen. I can read them with a Scanner without errors. I can also add a Woning without errors. If a Woning is added, the number on top of the file is incremented with 1.
Problem is as follows:
If a Woning has been added, the file has changed. The number is now 4, and a Woning has been added. However, if I want to read all the Woningen, Java returns an exception on the 4th Woning. So for some reason I can't read the 4th Woning.
What can be the cause of this? Do I have to save the file somehow after changes have been made to the file? Or something else has to be done?
Help is greatly appreciated :)!
EDIT
Note: Woning is the dutch word for House.
Code to read the file:
public static Portefeuille read (String infile) {
try {
Scanner sc = new Scanner (new File(infile));
ArrayList<Woning> wlijst = new ArrayList<Woning>();
Portefeuille p = new Portefeuille();
int woningen = sc.nextInt();
int i = 0;
while (i < woningen) {
sc.nextLine();
String tag = sc.nextLine();
wlijst.add(Woning.read(sc));
wlijst.get(i).setTag(tag);
//System.out.println(wlijst.get(i).getTag());
//System.out.println(wlijst.toString());
p.voegToe(wlijst.get(i));
i++;
}
sc.close();
return p;
}
catch (Exception e) {
System.out.println("Portefeuille: Exception is caught");
Portefeuille p = new Portefeuille();
return p;
}
}
Code to write to the file:
public static void writeToFile (Portefeuille port, int woningen) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Makelaar.txt", false)))) {
woningen = woningen + 1;
out.println(woningen);
ArrayList<Woning> wlijst = new ArrayList<Woning>();
wlijst = port.woninglijst;
for (int i = 0; i < wlijst.size(); i++) {
if (wlijst.get(i) instanceof KoopWoning) {
KoopWoning kw = (KoopWoning) wlijst.get(i);
KoopWoning.writeToFileK(kw, out);
}
else {
HuurWoning hw = (HuurWoning) wlijst.get(i);
HuurWoning.writeToFileH(hw, out);
}
}
out.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("writeToFile: Exception Caught");
}
}
File looks like this:
3
TE KOOP:
Emmalaan 23
3051JC Rotterdam
7 kamers
koopprijs 300000
energiepeil C
VERKOCHT:
Emmalaan 25
3051JC Rotterdam
5 kamers
vraagprijs 280000
energiepeil A
TE HUUR:
Javastraat 88
4078KB Eindhoven
3 kamers
huurprijs 500
I dont know what woningen is. But as far as I know, after adding the data to file, close the file and then try to read the data in file. This definition is always stuck in my mind that one should close the file after you've the finished your process. I can only guess whether you've done two java class for reading and writing or in a same class of writing and reading methods. Hereafter provide some codes so that all can atleast understand on what you're asking.
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.
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.
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.
The first part of this “Frankenstein-ed” Java works perfectly, however the second part outputs some jumbled nonsense. So the variable of result will be my input from the user. I had to first UpperCase the string before I did the parsing for some dumb reason, it’s hard when you come from the Database/Analysis background and know you do something in seconds and not get an error... I gave credit where credit is due within the code...
myfile.txt ---> [Ljava.lang.String;#19821f
import java.io.*;
/*http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split%28java.lang.String%29*/
public class StringParser {
public static void main (String arg[])
throws FileNotFoundException {
String result = "eggs toast bacon bacon butter ice beer".toUpperCase();
String[] resultU = result.split("\\s");
String[] y = resultU;
{
for (int x=0; x< resultU.length; x++)
System.out.println(resultU[x]);
/*http://www.javacoffeebreak.com/java103/java103.html#output*/
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
// Create a new file output stream
// connected to "myfile.txt"
out = new FileOutputStream("myfile.txt");
// Connect print stream to the output stream
p = new PrintStream( out );
p.println (resultU);
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
}
}
}
Do you realize you're overwriting the same file for each element in your array?
You should use
out = new FileOutputStream("myfile.txt", true); // appends to existing file
As well as printing the actual element, not the String representation of the whole array
p.println(resultU[x]); // resultU without index prints the whole array - yuk!
Although you should probably update your code to only create the output File once and just write each element of the array to the same output stream, as the current method is a bit inefficient.
Something like
public static void main(String[] args) {
String result = "eggs toast bacon bacon butter ice beer".toUpperCase();
PrintStream p = null;
try {
p = new PrintStream(new FileOutputStream("myfile.txt"));
for (String s : result.split("\\s")) {
p.println(s);
p.flush(); // probably not necessary
}
} catch (Exception e) {
e.printStackTrace(); // should really use a logger instead!
} finally {
try {
p.close(); // wouldn't need this in Java 7!
} catch (Exception e) {
}
}
}
You have to iterate the array and write each element one after one.
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
out = new FileOutputStream("myfile.txt");
p = new PrintStream( out );
for(String str:resultU)
{
p.println (str);
}
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
Your line
p.println (resultU);
is printing a string representation of the array itself, not the elements in it. To print the elements, you'll need to loop through the array and print them out individually. The Arrays class has a convenience method to do this for you, of course.
That "jumbled non-sense" is the Strings location in memory, but that's not important right now.
The solution to your problem is this:
try {
FileOutputStream out = new FileOutputStream("myfile.txt", true);
PrintStream = new PrintStream(out);
for(String s : resultU)
p.println(s);
p.close();
} catch(Exception e) {
e.printStackTrace();
}
This replaces your entire for loop.