Write file using BufferedWriter in Java [duplicate] - java

This question already has answers here:
BufferedWriter not writing everything to its output file
(8 answers)
Closed 8 years ago.
I am doing a lab where we have to read in an external file, take some statistics on the data, and then create and write a new file with the stats. Everything in my program works except for writing the file, which I cannot understand why my method won't work.
BufferedWriter writer;
public void writeStats(int word, int numSent, int shortest, int longest, int average)
{
try
{
File file = new File("jefferson_stats.txt");
file.createNewFile();
writer = new BufferedWriter(new FileWriter(file));
writer.write("Number of words: " + word );
writer.newLine();
writer.write("Number of sentences: " + numSent );
writer.newLine();
writer.write("Shortest sentence: " + shortest + " words");
writer.newLine();
writer.write("Longest sentence: " + longest + " words");
writer.newLine();
writer.write("Average sentence: " + average + " words");
}
catch(FileNotFoundException e)
{
System.out.println("File Not Found");
System.exit( 1 );
}
catch(IOException e)
{
System.out.println("something messed up");
System.exit( 1 );
}
}

You have to flush and close your writer:
writer.flush();
writer.close();

You should always close opend resources explicitly or implicitly with Java 7 try-with-resources
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
...
}
besides, there is a more convenient class to write text - java.io.PrintWriter
try (PrintWriter pw = new PrintWriter(file)) {
pw.println("Number of words: " + word);
...
}

You have to close your BufferedWriter using close():
writer.close();

Related

How to sort user input to text files in Java?

I have a program taking user input and setting students in a text file, I want to sort these students in separate text files using the grade average
import java.nio.file.*;
import java.io.*;
import static java.nio.file.StandardOpenOption.*;
import java.util.Scanner;
public class NewClass2
{
public static void main(String[] args)
{
String recOut = "";
String delimiter = ",";
Scanner input = new Scanner(System.in);
final int QUIT = 999;
NewClass1 student = new NewClass1();
try
{
System.out.println("Enter Student ID: ");
student.setStudentId(input.nextInt());
while(student.getStudentId() != QUIT)
{
System.out.println("Enter Student Last Name: ");
student.setLastName(input.next());
System.out.println("Enter Student First Name: ");
student.setFirstName(input.next());
System.out.println("Enter Student Grade Point: ");
student.setGradePoint(input.nextDouble());
if(student.getGradePoint()>=3.6)
{
Path fileOut = Paths.get("HonorsStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter + student.getLastName() + delimiter + student.getFirstName() + delimiter + student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
if(student.getGradePoint()<3.6 && student.getGradePoint()>=2.0)
{
Path fileOut = Paths.get("GoodStandingStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter + student.getLastName() + delimiter + student.getFirstName() + delimiter + student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
if(student.getGradePoint()<2.0)
{
Path fileOut = Paths.get("ProbationStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter
+ student.getLastName() + delimiter
+ student.getFirstName() + delimiter
+ student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
System.out.println("Enter Student ID: ");
student.setStudentId(input.nextInt());
}
}
catch(Exception e)
{
System.out.println("<<Something bad happened!>>");
System.out.println(e.getMessage());
}
}
}
I've been experimenting with if statements but that's not working because I can't close the writer correctly causing it to only take in one line then stopping.
How do I do this correctly?
The problem is not with how you're closing the file but with how your opening the file. Every time you're opening the file you are creating a new file and writing one line, then closing it, which is overwriting the old file that existed before. What you want to do is create the file if it does not exist, but if it does exist append one line.
Simply change
Files.newOutputStream(fileOut, CREATE)
to
Files.newOutputStream(fileOut, CREATE, APPEND)
Alternatively, you could open/close the files outside the loop or use “try with resources” too.
Since these are only three files, it is probably the easiest to open all three writers at once at the start and keep them open until the end.
If you don't want to close the writers manually (ans at least java 7 or 8 i think), you can use a try-with-resources statement.
Btw you probably don't need to wrap the OutputStream in a BufferedOutputStream, since you already use a buffered writer.
Instead of writing each time in file why don't you try to make three lists(one for every grade range you need) and when you have no more students then write them to separate files.
Something like this:
List<Student> honorsStudent = new ArrayList<Student>();
List<Student> goodStandingStudent = new ArrayList<Student>();
List<Student> probationStudent = new ArrayList<Student>();
// ....
if (student.getGrade() >= 3.6) {
honorsStudent.add(student);
} else if (student.getGrade() >= 2) {
goodStandingStudent.add(student);
}
else {
probationStudent.add(student);
}
//while loop end
//write your files

For-loop not executing File writing commands

I have a program that is supposed to generate a file with a random integer name and append 200 characters of data to each file. I have already succeeded in being able to create a file:
BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(
new File("C:/Users/mirvine/Desktop/SPAM").toPath()));
And I have gotten it to write chars to the file:
bos.write((char)rand.nextInt(255));
But when I combine the two with a for loop, it doesn't work:
try {
while(true) {
int i = rand.nextInt();
File outputFile = new File("C:/Users/mirvine/Desktop/SPAM/"+ String.valueOf(i) +".txt");
bos = new BufferedOutputStream(Files.newOutputStream(outputFile.toPath()));
PrintWriter writer = new PrintWriter(bos);
for(int qu = 0; qu <= 2000; qu++) {
writer.write((char)rand.nextInt(255));
System.out.println("Total " + String.valueOf(qu) + " characters written to " + String.valueOf(i) + ".txt!");
}
System.out.println("File named \'" + String.valueOf(i) + ".txt\' created!");
}
} catch (Exception e) {e.printStackTrace(); return;}
I will get the output "Total: (number) characters written to (whatever).txt!" but it won't actually write the characters. However, if I make the loop infinite (by changing qu++ to qu--) it will write the characters, of course with only one file though. I even tried changing it to a while loop and it didn't work. Any ideas?
Consider changing the use of BufferedOutputStream and PrintWriter for FileWriter, which will take your file as an argument to the constructor.
Also, make sure you flush and close the stream after finishing with it.
You should use a BufferedWriter, it's more efficient, and don't forget to close it at the end. The infinite loop is useless.
int i = rand.nextInt();
File outputFile = new File("C:/Users/mirvine/Desktop/SPAM/"+ String.valueOf(i) +".txt");
FileOutputStream fos = new FileOutputStream(outputFile);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));  
for(int qu = 0; qu <= 2000; qu++)
{
bw.write((char)rand.nextInt(255));
System.out.println("Total " + String.valueOf(qu) + " characters written to " + String.valueOf(i) + ".txt!");
}
bw.close();

Why does this code cause Java to write over the data in a file?

I am not sure as to why the following code causes Java to override the data already in my file every time, when what I want it to do is actually write each new piece of data on a new line. I have included the relevant pieces of code (I understand you might be thinking that there are errors in the variables, but there isn't, the program works fine). Can someone help me understand as to what is causing this, is is the way I am using the file writer?
String DirToWriteFile = System.getProperty("user.dir") + "/VirtualATM.txt"; //Get path to write text file to.
String Details = "Name: " + name + " CardNo: " + CardNo + " Current Balance: " + balance + " overdraft? " + OverDraft + " OverDraftLimit: " + OverDraftLimit + " pin: " + PinToWrite;
try{
//Create writer to write to files.
File file = new File(DirToWriteFile);
Writer bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader("VirtualATM.txt");
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
String CurrentData = "";
while((bufferedReader.readLine()) != null) {
line = CurrentData;
bw.write(CurrentData);
((BufferedWriter) bw).newLine();
}
bw.write(Details);
System.out.println("Account created!");
System.out.println(name + " Your card number is: " + CardNo);
// close the reader.
bufferedReader.close();
//Close the writer.
bw.close();
Use the other FileOutputStream constructor, the one that takes a boolean append parameter as the second parameter. Pass in true as this will tell Java to append text to the existing File rather than over-write it.
i.e., change this:
File file = new File(DirToWriteFile);
Writer bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
to this:
File file = new File(DirToWriteFile);
FileOutputStream fos = new FileOutputStream(file, true); // **note second param?**
Writer bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF8"));

Appending to text file then displaying only certain fields

I'm making a savings calculator using netbeans with a JFrameForm. below is my working code to save to a .txt. for some reason when I click save it will not append to a new line and wont save at all. I would like to then load certain rows to an array and display in my text area. eg the savings field. First code for the save button, second block for the load button.
BufferedWriter writer = null;
try{
writer = new BufferedWriter(new FileWriter("C:\\test.txt"));
writer.write("\n" + date + "\t" + gross + "\t" + tax + "\t" + savings);
}
catch (Exception e){
JOptionPane.showMessageDialog(null, "Error saving");
}finally{
try{
//close the writer
writer.close();
}catch (Exception e){
JOptionPane.showMessageDialog(null, "Error closing save");
}
}
try{
FileReader reader = new FileReader("C:\\test.txt");
BufferedReader br = new BufferedReader(reader);
txaMain.read(br, null);
br.close();
}
catch(Exception E){
JOptionPane.showMessageDialog(null, "Error opening file");
}
for some reason when I click save it will not append to a new line and wont save at all
It is not saving because you are not flushing the character buffer stream that was grab from your write method.
solution:
flush it after you write from the text file
writer = new BufferedWriter(new FileWriter("C:\\test.txt"));
writer.write("\n" + date + "\t" + gross + "\t" + tax + "\t" + savings);
writer.flush();
Also if you want to append to the file while saving the text then add one more parameter in your FileWriter FileWriter("C:\\test.txt, true") true means to append the file when writing.
public FileWriter(String fileName,
boolean append)

BufferReader.skip () performance

I can see vast difference in performance between below two programs.
import java.io.*;
import java.util.Date;
class SkipProg2 {
public static void main (String args[]) {
System.out.println (" File Reading "+ args.length);
System.out.println (" 1st Arg "+ args[0]);
System.out.println (" 2nd Arg "+ args[1]);
try {
FileInputStream fis = new FileInputStream(args[0]);
System.err.println("Time before skip : " + new Date());
Long off = Long.parseLong(args[1]);
fis.skip (off);
System.err.println("Time After skip : " + new Date());
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr );
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
} // end main
}
And
import java.io.*;
import java.util.Date;
class SkipProg {
public static void main (String args[]) {
System.out.println (" File Reading "+ args.length);
System.out.println (" 1st Arg "+ args[0]);
System.out.println (" 2nd Arg "+ args[1]);
try {
FileInputStream fis = new FileInputStream(args[0]);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr );
System.err.println("Time before skip : " + new Date());
Long off = Long.parseLong(args[1]);
br.skip (off);
System.err.println("Time After skip : " + new Date());
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
} // end main
}
One usage FileInputStream.skip () and another BufferReader.skip (). But, if offset value is bigger there vast different (For Ex. 8 Secs different for 2 GB)and in multithreaded application, the difference for the same code is huge (For 2 Gb offset there is around 15-20 mins delay). I cant replace BufferReader.skip () with FileInputStream.skip (), As one takes offset in terms of bytes and another in terms of chars. For unicode file, it is irreplaceable.
First question, whether my assumption is correct? what are suggestions?
Thanks In Advance.
The skip for bytes can skip that many bytes without reading them.
The skip for chars has to read all the chars/bytes up to that point to find where the Nth character is.
I am surprised it takes 15-20 mins to read 2 GB of text. I would have expected closer to 20 seconds. What sort of hardware do you have?
If you want random access in a text file, you need to maintain an index of line number to byte location (that way the time taken will bet the same)

Categories