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
Related
This is my code, I am trying to write a text file replacing "Up" and "Right" with ↑ and →. The problem is that the text file output is: "→ ↑"(this is not what i wanted) and the console output is "↑ →".
private static void print(String t){
File log = new File("a.txt");
String raw = t;
raw = raw.replaceAll("Up", " \u2191 "); //↑
raw = raw.replaceAll("Right", " \u2192 "); //→
try{
FileWriter fileWriter = new FileWriter(log, true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(raw + "\n");
System.out.println(raw + "\n")
bufferedWriter.close();
}catch(IOException e) {}
}
I think it may be an encoding error, but I dont know how to fix it.
First of all, it's best to specify the encoding (you probably want UTF-8) before you write your file.
private static void print(String t){
File log = new File("a.txt");
String raw = t;
raw = raw.replaceAll("Up", " \u2191 ");
raw = raw.replaceAll("Right", " \u2192 ");
try{
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(log), "UTF-8"));
bufferedWriter.write(raw + "\n");
System.out.println(raw + "\n");
bufferedWriter.close();
}catch(IOException e) {}
}
Then, you need to make sure that your file viewer is also set to UTF-8. It seems that your file viewer might be viewing the file in ANSI instead. Changing that setting would depend on your file viewer -- try Googling "[your file viewer name] UTF-8".
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.
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.
Ok so i am attempting to retrieve a .txt file from a server, write it to a local file and then be able to recall it later.
I noticed that i was not able to read back the file after i copied it locally
At first i thought it was something wrong with my read back code as when i open the file in wordpad or wordpad++ the content is present and written correctly as far as i can tell to the file.
However after much testing i determined there was nothing apparently wrong with the read back code.
So i added a test, i added some static writes to the code that does the copying:
bw.write("This is the test" + "\r\n");
bw.write("My first line!" + "\r\n");
bw.write("My second line ");
bw.write("keeps going on...P" + "\r\n");
Now when i run it everything writes correctly to the file (or appears to) but during read back only the static writes above are read.
Even though i can visually see the content in the file, the stuff that was copied from the web based file is (although present) never read back.
Any help would be appreciated
This is the code i am using to read and copy the file
** This is the file i am reading from on the web
CrewAdviceMasterControlURL = http://lialpa.org/CM3/CrewAdvices/advice_master.txt
public static String GetMasterFileStream(String Operation) throws Exception {
StringBuilder sb = new StringBuilder();
BufferedWriter bw = null;
String inputLine = null;
URL AdviceMasterControl = new URL(CrewAdviceMasterControlURL);
File outfile = new File("sdcard/CM3/advices/advice_master.txt");
if(!outfile .exists()){
outfile .createNewFile();
}
FileWriter fileWriter = new FileWriter(outfile);
bw = new BufferedWriter(fileWriter);
BufferedReader in = new BufferedReader(new InputStreamReader(AdviceMasterControl.openStream()));
System.out.println("Creating the master");
bw.write("This is the test" + "\r\n");
bw.write("My first line!" + "\r\n");
bw.write("My second line ");
bw.write("keeps going on...P" + "\r\n");
while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine); //for producing test output
sb.append((inputLine + "\r\n"));
bw.write(String.valueOf(inputLine) + "\r\n");
}
in.close();
bw.close();
return sb.toString();
}
and this is the code i am using to read it back
public static String GetLocalMasterFileStream(String Operation) throws Exception {
String FullPath = "/sdcard/CM3/advices/advice_master.txt";
System.out.println("path is " + FullPath);
File file = new File(FullPath);
if (file.canRead() == true) {System.out.println("-----Determined that file is readable");}
//Read text from file
StringBuilder text = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
line = br.readLine();
System.out.println("-----" + line);
while ((line = br.readLine()) != null) {
text.append(line);
System.out.println("-----" + line); //for producing test output
text.append('\n');
}
br.close();
return text.toString();
}
Solved this problem. The problem was with the txt file its self on the server. When the file was uploaded via FTP the ftp program was in auto. This seems to have forced the upload in binary instead of ASCII.
I re-uploaded in ASCII and it solved the problem.
I have this code here that takes in 3 arguments, A Directory, a Filename, and a number. The program creates the filename in the directory and writes the number in it. So I can say...
>java D: myName.txt Clay 100
which will create a file named myName.txt in D: and says 100 in it.
If myName is taken up, it changes the name to myName(2), then myName(3) (if myName(2) taken up). The only problem is that when it changes the name to myName(2) and writes, it overwrites myName. I dont want it to overwrite myName, I want it to just create a new file with that name. Ive looked at similar questions and the common answer is the flush and close the writer which ive done And it still doesnt work.
Any help would be appreciated, here is my code so fart...
import java.io.*;
public class filetasktest{
public static void main(String[] args) throws IOException{
int i = 2;
String directory = args[0];
if (directory.substring(directory.length() - 1) != "/"){
directory += "/";
}
String contactName = args[1];
String contactNumber = args[2];
String finalDirectory = directory + contactName + ".contact";
File f = new File(finalDirectory);
while (f.exists()){
finalDirectory = directory + contactName + "(" + ("" + i) + ")" + ".contact";
f.renameTo(new File(finalDirectory));
i++;
}
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(finalDirectory), "utf-8"));
writer.write(contactNumber);
} catch (IOException ex){
System.out.println(ex.getMessage());
} finally {
try {
writer.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
}
You need to use append mode
new BufferedWriter(new FileWriter(yourFileName, true));
here, true means that the txt should be appended at the end of file.
Check the FileWriter javadoc for more information.
Your problem is here:
while (f.exists()){
finalDirectory = directory + contactName + "(" + ("" + i) + ")" + ".contact";
f.renameTo(new File(finalDirectory));
i++;
}
The renameTo method does not change the path of a File object; it renames a file on disk. The path of f stays the same throughout the loop: it starts out as D:/myName.txt and if a file by that name exists, the file is renamed as D:/myName(1).txt. The variable f still holds the path D:/myName.txt, which no longer names a file, and the content is written to D:/myName(1).txt, overwriting the previous content.
To fix this issue change the loop to:
while (new File(finalDirectory).exists()){
finalDirectory = directory + contactName + "(" + ("" + i) + ")" + ".contact";
i++;
}
Take a look at FileInputStream(String, boolean) which will allow you to flag if the file should be appended or overwritten