BufferedWriter not writing to my text file - java

File outFile = new File("D:\\output.txt");
BufferedWriter wb = new BufferedWriter(new FileWriter(outFile));
while (resultSet.next()) {
int attr_id = resultSet.getInt("int_id");
String stringValue = resultSet.getString("StringValue");
String name = resultSet.getString("Name");
int index = stringValue.indexOf(".");
int valueLength = stringValue.length();
if(isNumeric(stringValue)) {
//if(index != -2 ) {
if(index != (valueLength - 2)) {
String string1 = Double.valueOf(stringValue).toString();
System.out.println("converted values : " +string1);
System.out.println("stringValue : " +stringValue);
System.out.println("intValue : " +int_id);
wb.write( stringValue + "," + int_id + "," + string1 );
wb.newLine();
}
}
}
Above is my part of the code, from resultset i'm writing the data into a file. However the code is not printing values in output.txt file but i could see the result in console.
if i remove the commented line and comment if(index != (valueLength - 2)) { this line, the java code is creating output.txt with values.
What's wrong?

probably need to just call flush and/or close on your BufferedWriter when you are done.

The reason why your code is not writing to the file is because you never push the data from the Writer to the actual file.
Think of BufferedWriters as an email you are sending to a coworker. When you use:
wb.write( stringValue + "," + int_id + "," + string1 );
it is like you are typing the email to your coworker, and defining the message to them. BUT, since you did not press "send email", your coworker will never see the message. The same concept can be applied here.
You are filling the writer with a bunch of data, but you are never sending the data to the file that you are trying to write to. There are two ways that you can do this, the first being to "flush" the writer (see documentation HERE). You can do this by calling
wb.flush();
This is the equivalent of pressing "send email", and will write the data to the file that you are editing. The second method would be to "close" the writer (see documenation HERE). The reason that this works is because the BufferedWriter's close method flushes the stream first, before closing the stream. This can be done by calling
wb.close();
Although, it would not be wise to do so until you are fully done editing the file, as it can no longer be accessed.
The following is your code edited to flush the stream after every record you are writing, and then close the stream after all records have been processed. Note the locations of wb.flush() and wb.close().
File outFile = new File("D:\\output.txt");
BufferedWriter wb = new BufferedWriter(new FileWriter(outFile));
while (resultSet.next()) {
int attr_id = resultSet.getInt("int_id");
String stringValue = resultSet.getString("StringValue");
String name = resultSet.getString("Name");
int index = stringValue.indexOf(".");
int valueLength = stringValue.length();
if(isNumeric(stringValue)) {
//if(index != -2 ) {
if(index != (valueLength - 2)) {
String string1 = Double.valueOf(stringValue).toString();
System.out.println("converted values : " +string1);
System.out.println("stringValue : " +stringValue);
System.out.println("intValue : " +int_id);
wb.write( stringValue + "," + int_id + "," + string1 );
wb.newLine();
wb.flush();
}
}
}
wb.close();

Related

FileReaders readLine return always null JAVA

Writing a program in java I'm trying to read the content of a file which is treated as a storage. I have a function to modify the amount of an object in the store, which is organized with one line per product, where the first word is the prodCode, and the second is the amount of it.
This is the function:
public static void modifyAmount(String prodCode, String newAmount){
try{
File magazzino = new File("Magazzino.txt");
BufferedReader fromFile = new BufferedReader(new FileReader("Magazzino.txt"));
FileWriter toFile = new FileWriter(magazzino);
String oldContent="";
String line;
String lineToReplace = prodCode + " " + amountRequest(prodCode);
String newLine = prodCode + " " + newAmount;
while((line = fromFile.readLine()) != null){
oldContent = oldContent + line + "\n";
System.out.println("leggendo " + line);
}
System.out.println(oldContent);
String newContent = oldContent.replaceAll(lineToReplace, newLine);
toFile.write(newContent);
toFile.close();
fromFile.close();
}catch(IOException e){
e.printStackTrace();
}
}
And the result of it is that it won't enter the while cycle because the first readLine result null, though the file is correctly formatted, the 'amountRequest' function works properly and the input is correct.
Magazzino.txt:
1 12
3 25
4 12
You're probably having trouble because you're trying to read and write the file at the same time, with different file handles. I'd suggest reading the file first, then closing the FileReader, then creating a FileWriter to write to it.
The issue is that before you have read the contents of the file, you are creating an instance of FileWriter which will clear the file.
FileWriter toFile = new FileWriter("Magazzino.txt"); will clear the file
The solution is to just create the instance of FileWriter after you are done reading the file.
public static void modifyAmount(String prodCode, String newAmount){
try{
File magazzino = new File("Magazzino.txt");
BufferedReader fromFile = new BufferedReader(new FileReader("Magazzino.txt"));
String oldContent="";
String line;
String lineToReplace = prodCode + " " + amountRequest(prodCode);
String newLine = prodCode + " " + newAmount;
while((line = fromFile.readLine()) != null){
oldContent = oldContent + line + "\n";
System.out.println("leggendo " + line);
}
fromFile.close();
System.out.println(oldContent);
String newContent = oldContent.replaceAll(lineToReplace, newLine);
FileWriter toFile = new FileWriter(magazzino);
toFile.write(newContent);
toFile.close();
}catch(IOException e){
e.printStackTrace();
}
}
You open a file twice, simultaneously for reading and writing.
As soon as you do this line,
FileWriter toFile = new FileWriter(magazzino);
your file is erased. Check it yourself.
Actually, with this line you are creating a new empty file for writing instead of the old one.
I'd suggest read file, then close, then write.
You can also try to pen file for append : new FileWriter("filename.txt", true);
This will not erase old file, allowing you to read it. But the new data will be appended to the end, though.
If you want to use you file as a state or storage, I'd suggest to look at sqlite: https://www.sqlite.org/index.html

Why does my program read only the first record in my files?

I have written this program to compare 2 files. They are 500mb to 2.8gb in size and are created every 6 hours. I have 2 files from 2 sources (NMD and XMP). They are broken up into lines of text that have fields separated by the pipe(|) character. Each line is a single record and may be up to 65,000 characters long. The data is about TV shows and movies, showing times and descriptive content. I have determined that any particular show or movie has a minimum of 3 pieces of data that will uniquely identify that show or movie. IE: CallSign, ProgramId and StartLong. The two sources for this data are systems called NMD and XMP hence that acronym added to various variables. So my goal is to compare a file created by NMD and one created by XMP and confirm that everything that NMD produces is also produced by XMP and that the data in each matched record is the same.
What I am trying to accomplish here is this:
1. Read the NMD file record by record for the 3 unique data fields.
2. Read the XMP file record by record and look for a match for the current record in the NMD file.
3.The NMD file should iterate one record at a time. Each NMD record should then be searched for in the entire XMD file, record by record for that same record.
4. Write a log entry in one of 2 files indicating success or failure and what that data was.
What is happening is the first record in each file is read, but then no records after that get read. As a result, the end of neither file is ever reached and no matches are ever found. My success.log and failure.log file never show any data in them. In the outer do/while loop, System.out displays a single line of text. IE: The first record in the file. In the inner do/while loop System.out prints the same data over and over and over which is also from the first record in the file. Isn't this proof that the program isn't iterating record by record through the two source files?
So onto the actual code...
import java.io.*;
public class FileParse {
public static void main(String[] args) throws java.io.IOException {
String epgsRecordNMD = null;
String epgsRecordXMP = null;
BufferedWriter logSuccessWriter = null;
BufferedWriter logFailureWriter = null;
BufferedReader readXMP = null;
BufferedReader readNMD = null;
readNMD = new BufferedReader(new FileReader("d:testdataNMD.txt"));
do {
epgsRecordNMD = readNMD.readLine();
String[] epgsSplitNMD = epgsRecordNMD.split("\\|");
String epgsCallSignNMD = epgsSplitNMD[0];
String epgsProgramIdNMD = epgsSplitNMD[2];
String epgsStartLongNMD = epgsSplitNMD[9];
System.out.println("epgsCallsignNMD: " + epgsCallSignNMD + " epgsProgramIdNMD: " + epgsProgramIdNMD + " epgsStartLongNMD: " + epgsStartLongNMD );
do {
readXMP = new BufferedReader(new FileReader("d:testdataXMP.txt"));
epgsRecordXMP = readXMP.readLine();
String[] epgsSplitXMP = epgsRecordXMP.split("\\|");
String epgsCallSignXMP = epgsSplitXMP[0];
String epgsProgramIdXMP = epgsSplitXMP[2];
String epgsStartLongXMP = epgsSplitXMP[9];
System.out.println("epgsCallsignXMP: " + epgsCallSignXMP + " epgsProgramIdXMP: " + epgsProgramIdXMP + " epgsStartLongXMP: " + epgsStartLongXMP);
if (epgsCallSignXMP.equals(epgsCallSignNMD) && epgsProgramIdXMP.equals(epgsProgramIdNMD) && epgsStartLongXMP.equals(epgsStartLongNMD)) {
logSuccessWriter = new BufferedWriter (new FileWriter("d:success.log", true));
logSuccessWriter.write("NMD match found in XMP" + "epgsCallsignNMD: " + epgsCallSignNMD + " epgsProgramIdNMD: " + epgsProgramIdNMD + " epgsStartLongNMD: " + epgsStartLongNMD);
logSuccessWriter.write("\n");
logSuccessWriter.close();
System.out.println ("Match found");
}
} while (epgsRecordXMP != null);
logFailureWriter = new BufferedWriter (new FileWriter("d:failure.log", true));
logFailureWriter.write("NMD match not found in XMP" + "epgsCallsignNMD: " + epgsCallSignNMD + " epgsProgramIdNMD: " + epgsProgramIdNMD + " epgsStartLongNMD: " + epgsStartLongNMD);
logFailureWriter.write("\n");
logFailureWriter.close();
System.out.println ("Match NOT found");
} while (epgsRecordNMD != null);
readNMD.close();
readXMP.close();
}
}
do {
readXMP = new BufferedReader(new FileReader("d:testdataXMP.txt"));
You sure you want this in a loop? You are opening the same file over and over again.
Why not do something like this?
BufferedReader br = new BufferedReader(new FileReader("whateverfile.dat"));
BufferedReader br2 = new BufferedReader(new FileReader("whateverfile2.dat"));
String data;
String data2;
while(data = br.readLine() != null)
{
// do whatever you want, for example found 3 unique records
while(data2 = br2.readLine() != null)
{
// do whatever you want
}
}
Just like what OldProgrammer said, you're opening the file multiple times. You just need to ensure that the reader / streamer is open and iterate whatever you want then close it.

Logic issue to update text file - Java

I'm having a logic issue to update a text file via user input.
I have a text file containing product information (ID;Name;Cost;Stock) :
001;Hand Soap;2.00;500
In order to add a product the user calls a function addProduct in order to either update a product if the product name already exists in the file or append to the text file if it does not yet exist. I'm unsure of two things : how to append only once (for the moment it's appending for every line it reads..) and how to deal with an empty text file.
This is how addProduct looks:
public void addProduct(Product product, int amountReceived) throws FileNotFoundException, IOException {
newProduct = product;
String productParams = newProduct.getProduct();
String productID = newProduct.getProductID();
int productStock = newProduct.getProductStock();
String productName = newProduct.getProductName();
String tempFileName = "tempFile.txt";
System.out.println("Attempting to Add Product : " + newProduct.getProduct());
BufferedReader br = null;
BufferedWriter bw = null;
try {
FileInputStream fstream = new FileInputStream(ProductMap.productFile);
br = new BufferedReader(new InputStreamReader(fstream));
String line;
StringBuilder fileContent = new StringBuilder();
while ((line = br.readLine()) != null) {
System.out.println("Line : " + line);
String [] productInfo = line.split(";");
System.out.println("Added Product Info length : " + productInfo.length);
if (productInfo.length > 0) {
if (productInfo[1].equals(productName))
{
System.out.println("Adding existing product");
System.out.println("Product Info : " + String.valueOf(productInfo[3]));
//line = line.replace(String.valueOf(productInfo), String.valueOf(productStock - amountSold));
productInfo[3] = String.valueOf(Integer.parseInt(productInfo[3]) + amountReceived);
String newLine = productInfo[0] + ";" + productInfo[1] + ";" + productInfo[2] + ";" + productInfo[3];
fileContent.append(newLine);
fileContent.append("\n");
System.out.println("Updated Product Info : " + String.valueOf(Integer.parseInt(productInfo[3]) + amountReceived));
System.out.println("Line :" + newLine);
} else {
fileContent.append(line);
fileContent.append("\n");
fileContent.append(productParams);
fileContent.append("\n");
//fileContent.append(productParams + "\n");
//System.out.println("Product Name : " + productInfo[1]);
//System.out.println("The full product info : " +productParams);
}
}
br.readLine();
}
if (br.readLine() == null) {
fileContent.append(productParams);
}
System.out.println("Product Updated File Contents : " + fileContent);
FileWriter fstreamWrite = new FileWriter(ProductMap.productFile);
BufferedWriter out = new BufferedWriter(fstreamWrite);
System.out.println("File Content : " + fileContent);
out.write(fileContent.toString());
out.close();
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
At a high level, a simple text file may not be the best choice for this use. This implementation requires enough memory to hold the entire file.
If you only had additions and could just append to the file directly, things would be easier. A database would seem to be the best choice. Somewhere between a database and a simple text file, a RandomAccessFile could help if the data could be written with standard lengths for each field. Then you could overwrite a particular row rather than having to rewrite the whole file.
Given the constraints of the current setup, I can't think of a way around writing all the data each time the file is updated.
To get around the empty file problem, you could skip the else condition of the current loop So the new data would not be added to the fileContent StringBuffer. Then when writing the data back out, you could either write the new data before or after the other information from the file.
Also, the readLine at the bottom of the loop is not needed. Any row that is read at the bottom of the loop will be skipped over and not really processed when the read at the top of the loop gets the next line.

Split strings with an "Enter"

I have code that splits a string into 3 strings, then prints them. I want each one to be separated by the equivalent of an "Enter". Here's the code:
String accval = text;
try {
PrintWriter writer = new PrintWriter(new BufferedWriter(
new FileWriter("sdcard/YS Data/Accelerometer.html",
true)));
String[] tempArr = accval.split("\\s+");
String x = tempArr[0] + "_"; //I want the enter to be where the underlines are:
String y = tempArr[1] + "_";
String z = tempArr[2] + "_";
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>" + x + y
+ z + "</h3><br>");
}
writer.flush();
writer.close();
} catch (IOException e) {
// put notification here later!!!
e.printStackTrace();
}
This outputs:
x=-0.125_y=0.9375_z=0.375
x=-0.125_y=0.9375_z=0.375
with the strings separated by underscores.
However, I want it to look like this:
x=-0.125
y=0.9375
z=0.375
x=-0.125
y=0.9375
z=0.375
Thanks for any help.
EDIT:
I've implemented the answer of #Julius in the following code that prints how I wanted it:
Code:
String accval = text;
try {
PrintWriter writer = new PrintWriter(new BufferedWriter(
new FileWriter("sdcard/YS Data/Accelerometer.html",
true)));
String[] tempArr = accval.split("\\s+");
String x = tempArr[0];
String y = tempArr[1];
String z = tempArr[2];
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>" + x + "<br>" + y + <br>
+ z + "</h3><br>");
}
writer.flush();
writer.close();
} catch (IOException e) {
// put notification here later!!!
e.printStackTrace();
}
Which prints:
x=0.25
y=125
z=1.23
x=0.125
y=725
z=0.935
if you want the line returns to be displayed in the browser, this is the way to go:
writer.println("<h3 style=padding-left:20px;>" + x + "<br/>" + y + "<br/>" + z + "<br/></h3>");
You can use
System.getProperty("line.separator")
to get a line separator.
You could explicitly write CR+LF as in the other answers here. You can also use the default line break by just using println separately for each item, e.g.:
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>");
writer.println(x);
writer.println(y);
writer.println(z);
writer.println("</h3><br>");
}
This is slightly more verbose but won't run into inconsistent line-break issues on systems where CRLF is not the default line ending.
Note, however, that the linebreaks in the HTML probably won't be rendered, unless your CSS specifies that they should be. You probably want to just write a "<br>" tag after each element instead of an actual line break, e.g.:
writer.println("<h3 style=padding-left:20px;>");
writer.println(x + "<br>");
writer.println(y + "<br>");
writer.println(z + "<br>");
writer.println("</h3><br>");
You wouldn't have to use println for this (you could use print or just concatenate as you were doing before), but it does make the generated source a bit more readable.
Off topic, your use of linebreaks in an "<h3>" header tag isn't really semantically appropriate. A "<div>" with appropriate styling would be a more accurate representation, unless these are actually serving as section headers.
"\r\n" is the correct string for a line break on Windows systems; "\n" is correct on Linux and other Unix-based systems. This will work on either type of system:
String newline = String.format("%n");
which will set newline to "\r\n" or "\n" as appropriate (or perhaps some other sequence on some OS's from a different planet :)
EDIT:%n by definition inserts System.getProperty("line.separator") as noted in another answer. So these are equivalent.

Reading multiple records from a flat file in Java

I have a text file dump that I need to convert to a delimited file. The file contains a series of "records" (for lack of a better word) formatted like this:
User: abc123
Date: 7/3/12
Subject: the foo is bar
Project: 123456
Problem: foo bar in multiple lines of text
Resolution: foo un-barred in multiple lines of text
User: abc123
Date: 7/3/12
Subject: the foo is bar
Project: 234567
Problem: foo bar in multiple lines of text
Resolution: foo un-barred in multiple lines of text
...
My end result is to get a flat file of delimited values. Using the records above, we would see:
abc123;7/3/12;the foo is bar;123456;foo bar in multiple lines of text;foo un-barred in multiple lines of text
abc123;7/3/12;the foo is bar;234567;foo bar in multiple lines of text;foo un-barred in multiple lines of text
Code appears below, and following that, the problem I'm experiencing.
import java.util.*;
import java.io.*;
import java.nio.file.*;
//
public class ParseOutlookFolderForSE
{
public static void main(String args[])
{
String user = "";
String PDLDate = "";
String name = "";
String PDLNum = "";
String problemDesc = "test";
String resolutionDesc = "test";
String delim = ";";
int recordCounter = 0;
//
try
{
Path file = Paths.get("testfile2.txt");
FileInputStream fstream = new FileInputStream("testfile2.txt");
// Get the object of DataInputStream
/* DataInputStream in = new DataInputStream(fstream); */
BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); //Buffered Reader
String inputLine = null; //String
StringBuffer theText = new StringBuffer(); //StringBuffer
// problem: output contains last record ONLY. program is cycling through the entire file, overwriting records until the end.
// add a for loop based on recordCounter
for(recordCounter=0;recordCounter<10;recordCounter++)
{
while((inputLine=br.readLine())!=null)
{
if(inputLine.toLowerCase().startsWith("from:"))
{
/* recordCounter = recordCounter++; */ // commented out when I added recordCounter++ to the for loop
user = inputLine.trim().substring(5).trim();
}
else
if(inputLine.toLowerCase().startsWith("effective date"))
{
PDLDate = inputLine.trim().substring(15).trim();
}
else
if(inputLine.toLowerCase().startsWith("to:"))
{
name = inputLine.trim().substring(3).trim();
}
else
if(inputLine.toLowerCase().startsWith("sir number"))
{
PDLNum = inputLine.trim().substring(12).trim();
}
} //close for loop
} // close while
System.out.println(recordCounter + "\n" + user + "\n" + name + "\n" + PDLNum + "\n" + PDLDate + "\n" + problemDesc + "\n" + resolutionDesc);
System.out.println(recordCounter + ";" + user + ";" + name + ";" + PDLNum + ";" + PDLDate + ";" + problemDesc + ";" + resolutionDesc);
String lineForFile = (recordCounter + ";" + user + ";" + name + ";" + PDLNum + ";" + PDLDate + ";" + problemDesc + ";" + resolutionDesc + System.getProperty("line.separator"));
System.out.println(lineForFile);
try
{
BufferedWriter out = new BufferedWriter(new FileWriter("testfileoutput.txt"));
out.write(lineForFile);
out.close();
}
catch (IOException e)
{
System.out.println("Exception ");
}
} //close try
catch (Exception e)
{
System.err.println("Error: " + e.getMessage());
}
}
}
My final output is ONLY the last record. I believe that what's happening is that the program is reading every line, but only the LAST one doesn't get overwritten with the next record. Makes sense. So I added a FOR loop, incrementing by 1 if(inputLine.toLowerCase().startsWith("user:")) and outputting the counter variable with my data to validate what's happening.
My FOR loop begins after step 3 in my pseudocode...after BufferedReader but before my IF statements. I terminate it after I write to the file in step 6. I'm using for(recCounter=0;recCounter<10;recCounter++) and while I get ten records in my output file, they are all instances of the LAST record of the input file, numbered 0-9.
Leaving the for loop in the same place, I modified it to read for(recCounter=0;recCounter<10;) and placed recCounter's increment WITHIN the IF statement, incrementing every time the line starts with User:. In this case, I also got ten records in my output file, they were ten instances of the last record in the input file, and all the counters are 0.
EDIT: Given how the file is formatted, the ONLY way to determine w=one record from the next is a subsequent instance of the word "User:" at the start of the line. Each time that occurs, until the NEXT time it occurs is what constitutes a single record.
It appears as though I'm not setting my "recCounter" appropriately, or I'm not interpreting the results of what IS being set as "start a new record".
Anyone have any suggestions for how to read this file as multiple records?
Okay, so your pseudo-code should go something like this:
declare variables
open file
while not eof
read input
if end of set
format output
write output
clear variables
figure out which variable
store in correct variable
end-while
There might be a trick to figuring out when you've finished one set and can start the next. If a set is supposed to be terminated by a blank line as appears from your example, then you could just check for the blank line. Otherwise, how do you know? Does a set always start with "user"?
Also, don't forget to write the last record. You don't want to leave unwritten stuff in your buffer/table.
From your description it sounds like the following is the case: you are actually not writing the output strings as you complete them, but instead doing all of the writing at the end. It does not sound like you are saving the output strings outside of the loop, and so each time you find a record, you are overwriting the output string you previously calculated.
You should test that you are actually writing to the file after each record is found and has its output string created.
Without posting your code, I am not sure I can help you much further.

Categories

Resources