While creating a method to my class, I got an unexpected problem. I've tried solutions from other theards, but they just don't work for me. My method should simply find the line specified, copy the file skipping unnecessary line, delete the original file and rename temporary file to the name of original file. It succesfuly creates new file as expected, but then fails to delete previous one as it fails to rename temporary file to original. I can't figure out, why?
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
File filePath = new File(path);
BufferedReader reader = new BufferedReader(new FileReader(file_name + ".txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
filePath.delete();
temp.renameTo(theFile);
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
Try this code:
void lineDelete(String file_name, String line_to_erase){
try {
int line_number = 0;
String newline = System.getProperty("line.separator");
File temp = new File("temporary.txt");
File theFile = new File(file_name+".txt");
String path = theFile.getCanonicalPath();
BufferedReader reader = new BufferedReader(new FileReader(theFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
String lineToRemove = line_to_erase;
String currentLine;
while((currentLine = reader.readLine()) != null) {
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine + newline));
}
writer.close();
reader.close();
theFile.delete();
temp.renameTo(file_name + ".txt");
}
catch (FileNotFoundException e){
System.out.println(e);
}
catch (IOException e){
System.out.println(e);
}
I could suggest a couple of reasons why the delete and/or rename might fail, but there is a better way to solve your problem than guessing1.
If you use Path and the Files.delete(Path) and Files.move(Path, Path, CopyOption...) methods, they will throw exceptions if the operations fail. The exception name and message should give you clues as to what is actually going wrong.
The javadoc is here and here.
1 - Here are a couple of guesses: 1) the file has been opened elsewhere, and it is locked as a result. 2) You don't have access to delete the file.
Related
I am using a BufferedReader to read a file and store each line in a String ArrayList. However, after running the BufferedReader, reading the file, storing it, and printing the ArrayList, I get something different from the original file.
My code to read file:
public File shooterUIFile = new File("./src/com/xyfurion/hudedit/bin/resources/ShooterUI.ini");
public ArrayList<String> shooterUIRead = new ArrayList<>();
public ArrayList<String> shooterUIWrote = new ArrayList<>();
public void readHUDFile(){
try {
FileReader fileReader = new FileReader(shooterUIFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while (bufferedReader.readLine() != null)
shooterUIRead.add(bufferedReader.readLine());
for (int i = 0; i < shooterUIRead.size(); i++)
System.out.println(shooterUIRead.get(i));
bufferedReader.close();
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" + shooterUIFile + "'");
ex.printStackTrace();
}
catch(IOException ex) {
System.out.println("Error reading file '" + shooterUIFile + "'");
ex.printStackTrace();
}
}
Output (File printed): PASTEBIN
Original File: PASTEBIN
You are only keeping every other line , since you are calling readLine twice each iteration and discarding the first read line (the one in the while condition).
You may avoid it this way :
String line = null;
while ((line = bufferedReader.readLine()) != null)
shooterUIRead.add(line);
I'm creating a program to remove doctors from an arrayList that is utilising a queue. This works the first time perfectly however, the second time it's duplicating the data inside the text file. How can I solve this?
/**
*
* #throws Exception
*/
public void writeArrayListToFile() throws Exception {
String path = "src/assignment1com327ccab/DoctorRecordsFile.txt";
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(path));
BufferedWriter br = new BufferedWriter(os);
PrintWriter out = new PrintWriter(br);
DoctorNode temp; //create a temporary doctorNode object
temp = end; //temp is equal to the end of the queue
//try this while temp is not equal to null (queue is not empty)
StringBuilder doctor = new StringBuilder();
while (temp != null) {
{
doctor.append(temp.toStringFile());
doctor.append("\n");
//temp is equal to temp.getNext doctor to get the next doctor to count
temp = temp.getNext();
}
}
System.out.println("Finished list");
System.out.println("Doctors is : " + doctor.toString());
out.println(doctor.toString());
System.out.println("Done");
br.newLine();
br.close();
}
This is not 100% solution but I think it will give you the right directions. I don't want to do 100% work for you :)
In my comment I said
Read file content
Store it in variable
Remove file
Remove doctors from variable
Write variables to new file
So, to read file content we would use something file this (if it's txt file):
public static String read(File file) throws FileNotFoundException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file.getAbsoluteFile()));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
if (line != null) sb.append(System.lineSeparator());
}
String everything = sb.toString();
return everything;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
This method returns String as file content. We can store it in a variable like this:
String fileContent = MyClass.read(new File("path to file"));
Next step would be to remove our file. Since we have it in memory, and we don't want duplicate values...
file.delete();
Now we should remove our doctors from fileContent. It's basic String operations. I would recommend using method replace() or replaceAll().
And after the String manipulation, just write fileContent to our file again.
File file = new File("the same path");
file.createNewFile();
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file, true), "UTF-8"));
out.write(fileContent);
out.flush();
out.close();
What i'm trying to do, is to replace a symbol in a file text which contains over 4000 lines but using the below code, after the program ends, it only remain 500 lines. Why is this file truncated? How to solve this?
This is my code:
ArrayList<String> arrayList = new ArrayList<>();
try (FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.replace("þ", "t");
arrayList.add(line);
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
for (String string : arrayList) {
bw.write(string + "\n");
}
} catch (Exception e) {System.err.println(e);}
}
} catch (Exception e) {e.printStackTrace();}
Thanks in advance!
new BufferedWriter(new FileWriter(file)) clear file.
You should open it only once. Also you reading and writing to the same file. You should use different files.
Like this
try (FileReader fileReader = new FileReader(inputFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.replace("þ", "t");
bw.write(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
You are writing to the same file while you are reading it. This won't work. Once you start writing, the file becomes empty (plus whatever you've written), so subsequent reads will report end-of-file. Your ~500 lines will be buffered input from the first read.
One solution is to do all the reading first, before opening the file again for writing:
Array<String> arrayList = new ArrayList<>();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
while ((String line = bufferedReader.readLine()) != null) {
line = line.replace("þ", "t");
arrayList.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
for (String string : arrayList) {
bw.write(string + "\n");
}
} catch (Exception e) {
System.err.println(e);
}
Here, first the program slurps the file into a List<String>, fixing the lines as it goes. Then it writes all the lines back out to the file.
There are circumstances in which this model is appropriate. For example, you might be building a non-linear data structure from the file content. Or you might need to see the last line before you can modify earlier lines (and be unable to re-open the data source from the start).
However I'd suggest a method that's more thrifty with memory. You don't need to keep all those lines in memory. You can read one line, fix it up, then forget about it. But to do this, you'll need to write to a second file.
String filein = "inputfile";
String fileout = filein + ".tmp";
try(
BufferedReader reader = new BufferedReader(new FileReader(filein));
Writer writer = new BufferedWriter(FileWriter(fileout))
) {
while ((String line = bufferedReader.readLine()) != null) {
writer.write(line.replace("þ", "t");
}
}
Files.move(Paths.get(fileout)),
Paths.get(filein),
CopyOption.REPLACE_EXISTING);
I have left out the necessary exception catching -- add back in as required.
This question already has answers here:
BufferedWriter not writing everything to its output file
(8 answers)
Closed 8 years ago.
Aim: The server reads in data from a text file sent by a client. The server stores this data in another text file.
Problem: I am able to read in the text file and print it to the console however, when i run my code with the BufferedWriter and open the new textfile after, the file is empty. I am not entirely sure whether i have used the BufferedWriter function incorrectly or if i am missing any key functions out?
Code:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while (true) {
fromUser = stdIn.readLine();
if (fromUser != null) {
FileReader file = new FileReader("client-temp.txt");
BufferedReader tc = new BufferedReader(file);
BufferedWriter bw = new BufferedWriter(new FileWriter("datastore.txt"));
String line;
while ((line = tc.readLine()) != null)
{
String[] data = line.split(",");
String sensortype = data[0];
String date = data[1];
String time = data[2];
String reading = data[3];
String newdata = sensortype + date + time + reading;
System.out.println(line);
if (line != null)
{
out.write(line);
out.flush();
}
System.out.println("Data sent to file");
}
System.out.println(EmsClientID + " sending " + fromUser + " to EmsServer");
out.println(fromUser);
}
fromServer = in.readLine();
System.out.println(EmsClientID + " received " + fromServer + " from EmsServer");
}
You never call flush or close on the instance of BufferedWriter, in fact, you ignore it completely. Also, you resource management is none existent. If you open a resource, you should close it.
For example...
FileReader file = new FileReader("client-temp.txt");
try (BufferedReader tc = new BufferedReader(file)) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("datastore.txt"))) {
String line;
while ((line = tc.readLine()) != null)
{
String[] data = line.split(",");
String sensortype = data[0];
String date = data[1];
String time = data[2];
String reading = data[3];
String newdata = sensortype + date + time + reading;
System.out.println(line);
if (line != null)
{
bw.write(line);
bw.newLine();
}
System.out.println("Data sent to file");
}
} catch (IOException exp) {
exp.printStackTrace();
}
} catch (IOException exp) {
exp.printStackTrace();
}
See The try-with-resources Statement for more details
(ps: You can compound the try-with-resource statement, opening multiple resources within the same try (...) { section, but I wanted to demonstrate the basic concept)
Your code is incomplete. I'm gonna go out on a whim here and assume your problem.
Add
out.close();
at the end of your code.
I need to load from text file text which I will be replacing in other string.
For example I have text file:
\n;(br)
After loading this file I need to change all break lines to (br) so I will receive one line string.
Problems is when I'm loading text from file - I don't get string \n;(br) but \\n;(br)
Anyone know how to do that?
My code - I know that I'm adding '\n' in method applyFilters but it is because that there can be situation when I don't whant to change that.
void loadSource(){
File file = new File(sourcePath);
BufferedReader reader=null;
String text;
try{
reader = new BufferedReader( new FileReader(file));
}catch(FileNotFoundException e){
e.printStackTrace();
}
try{
while((text = reader.readLine()) != null){
sourceText.add(text);
}
}catch(Exception e){
e.printStackTrace();
}
}
void loadFilters(){
File file = new File(filterPath);
BufferedReader reader=null;
String text;
try{
reader = new BufferedReader( new FileReader(file));
}catch(FileNotFoundException e){
System.out.println("Błąd, brak pliku źródłowego");
e.printStackTrace();
}
try{
while((text = reader.readLine()) != null){
filterText.add(text);
}
}catch(Exception e){
e.printStackTrace();
}
}
void applyFilters(){
for (String s : sourceText){
finalText = finalText+ s + "\n";
}
for(String filter : filterText)
{
finalText = finalText.replace(filter.split(";")[0],filter.split(";")[1]);
}
System.out.println(finalText);
}
It sounds like you want the "\n" in your text file to represent a newline character rather than a backslash followed by an n. Have a look at this question:
How to unescape a Java string literal in Java?