Java File cannot be deleted nor renamed - java

See my code below:
I can write a key and a string in one line of a file. If the key already exists I want to overwrite it by creating a new file and fill it with the content of my source file. In the end I am going to delete the old file and rename my temporary file. But it does not work. As you can see I print booleans for deleting and renameTo methods. Both are returned as "false".
I read in some other Threads that I have to close all Readers and Writers that are in contact with my file in order to be able to rename or delete it.
You see my fault?
(Note that some comments are written in german)
public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
if(key.length() <= 0 || value.length() <= 0) return false;
String pfilepath = rootdirectory.concat(filepath);
File pfile = new File(pfilepath);
//dini_Remove(filepath.concat(".part"));
if(dini_Exists(filepath) == false) return false;
// Checkt ob der Key schon existiert
FileReader fr = new FileReader(pfilepath);
BufferedReader br = new BufferedReader(fr);
String ausw;
boolean foundkeybool = false;
while((ausw = br.readLine()) != null)
{
String foundkey = ausw.substring(0,ausw.indexOf("="));
//System.out.println(foundkey);
if(foundkey.equals(key))
{
foundkeybool = true;
System.out.println(foundkeybool);
// Key exists and content has to be overwritten
String newline = key.concat("=").concat(value);
String tmpdir = rootdirectory.concat("tmp.tmp");
File tmp = new File(tmpdir);
tmp.createNewFile();
String currentLine;
FileWriter fw = new FileWriter(tmpdir);
BufferedWriter bw = new BufferedWriter(fw);
br.close();
fr.close();
fr = new FileReader(pfilepath);
br = new BufferedReader(fr);
while((currentLine = br.readLine()) != null)
{
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
System.out.println(trimmedLine);
if(trimmedLine.equals(ausw))
{
System.out.println("Austauschen: "+newline);
bw.write(newline);
}
else
{
bw.write(currentLine);
System.out.println("Lassen: "+currentLine);
}
bw.newLine();
}
br.close();
fr.close();
bw.close();
fw.close();
tmp.setWritable(true);
pfile.setWritable(true);
// boolean removed = dini_Remove(filepath);
boolean removed = pfile.delete();
System.out.println("Datei wurde gelöscht: "+removed);
boolean renamed = tmp.renameTo(pfile);
System.out.println("Datei umbenannt: "+renamed);
break;
}
}
// if key does now exists we can create a new one
if(foundkeybool == false)
{
FileWriter fw = new FileWriter(pfilepath,true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(key.concat("=").concat(value));
bw.newLine();
bw.close();
}
return true;
}

This may not fix your problem, but it will get you closer.
You MUST ensure that any resource that you open is closed properly. Currently in your code, if, for some reason, an exception is thrown, none of your resources will be closed.
Even if you're not interested in dealing with the exception within the method, you should still wrap the file access code within a try-finally block
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(pfilepath);
br = new BufferedReader(fr);
//...//
} finally {
try {
br.close();
} catch (Exception exp) {
}
try {
fr.close();
} catch (Exception exp) {
}
}
You may find that you only need to close the BufferedReader and it should be calling close on it's child Reader, but I'm paranoid about ensuring that everything is clean
If you are using Java 7, you may wish to take a look at The try-with-resources Statement
Updated
I'm not sure your code makes sense. Basically, what you should be doing, is reading the entire source file and writing it the temp location (as you don't know in advance if the key needs to be updated, and you would probably need to read the source file anyway to find out).
Once this has being completed, if you made changes to the temp file, delete the source file and rename the temp file into it's place.
You code seems mighty inefficient to me...

Okai, I want to give you a brief update about the code.
I changed it this way and for now it is working as it should.
Do you have some more things I can change to optimize the code?
public static boolean dini_Set(String filepath, String key, String value) throws IOException
{
if(key.length() <= 0 || value.length() <= 0) return false;
String pfilepath = rootdirectory.concat(filepath);
File pfile = new File(pfilepath);
//dini_Remove(filepath.concat(".part"));
if(dini_Exists(filepath) == false) return false;
// Checkt ob der Key schon existiert
boolean foundkeybool = false;
File tmp = null;
try(BufferedReader br = new BufferedReader(new FileReader(pfilepath)))
{
String ausw;
while((ausw = br.readLine()) != null)
{
String foundkey = ausw.substring(0,ausw.indexOf("="));
System.out.println(foundkey);
if(foundkey.equals(key))
{
foundkeybool = true;
System.out.println(foundkeybool);
//Key exists and content has to be overwritten
String newline = key.concat("=").concat(value);
String tmpdir = rootdirectory.concat("tmp.tmp");
tmp = new File(tmpdir);
tmp.createNewFile();
String currentLine;
try(BufferedWriter bw = new BufferedWriter(new FileWriter(tmpdir)))
{
try(BufferedReader br2 = new BufferedReader(new FileReader(pfilepath)))
{
while((currentLine = br2.readLine()) != null)
{
//trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
System.out.println(trimmedLine);
if(trimmedLine.equals(ausw))
{
System.out.println("Austauschen: "+newline);
bw.write(newline);
}
else
{
bw.write(currentLine);
System.out.println("Lassen: "+currentLine);
}
bw.newLine();
}
}
}
break;
}
}
}
if(foundkeybool == true)
{
tmp.setWritable(true);
pfile.setWritable(true);
//boolean removed = dini_Remove(filepath);
boolean removed = pfile.delete();
System.out.println("Datei wurde gelöscht: "+removed);
boolean renamed = tmp.renameTo(pfile);
System.out.println("Datei umbenannt: "+renamed);
}
else //(foundkeybool == false) if key does now exists we can create a new one
{
try(BufferedWriter bw = new BufferedWriter(new FileWriter(pfilepath,true)))
{
bw.write(key.concat("=").concat(value));
bw.newLine();
bw.close();
}
}
return true;
}

Related

Is my readers and writers in this method not closing properly?

When I delete a record first before inserting a new record, I can do it, and after deleting I can add new record. But if I insert a new record first then my delete function is not working. Based on my research, it's mainly because the input/output is not closed properly but I have already done that, please take a look at my source code thank you.
Insert record
public void RegCustomer()
{
try
{
File F = new File("Customer.txt");
FileWriter fw = new FileWriter(F, true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
//PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(F, true)));
pw.println(this.Name+","+this.CheckInDate+","+this.CheckOutDate+","+this.Floor+","+this.RoomID+","+this.ICNumber+","+this.Contact+","+this.Email);
pw.flush();
pw.close();
fw.close();
bw.close();
}
catch(Exception e)
{
}
}
Delete Record
public boolean delcus(String Target)
{
boolean success = false;
File F = new File("Customer.txt");
File Ftc = new File("Temp.txt");
try
{
FileReader fr = new FileReader(F);
BufferedReader br = new BufferedReader(fr);
PrintWriter pr = new PrintWriter(Ftc);
String line = br.readLine();
while (line!=null)
{
String[] wordsinLine = line.split(",");
if (wordsinLine[0].equals(Target))
{
}
else
{
pr.println(line);
success = true;
}
line = br.readLine();
}
if (success)
{
pr.flush();
pr.close();
br.close();
fr.close();
}
}
catch (Exception e)
{
}
F.delete();
File dump = new File("Customer.txt");
Ftc.renameTo(dump);
return success;
}
I have another method that checks for several conditions before triggering the insert method.
public int checkroom()
{
int check = 0;
int ciDay = this.CheckInDate/10000;
int ciMonth = (this.CheckInDate/100)%100;
int coDay = this.CheckOutDate/10000;
int days = coDay - ciDay;
String name;
int Dbcid;
int Dbcod;
int DbFloor;
int DbRoomID;
try
{
File F = new File("Customer.txt");
FileReader Fr = new FileReader(F);
BufferedReader Reader = new BufferedReader(Fr);
Scanner Sc = new Scanner(Reader);
Sc.useDelimiter("[,\n]");
while(Sc.hasNext())
{
name = Sc.next();
Dbcid = Sc.nextInt();
Dbcod = Sc.nextInt();
DbFloor = Sc.nextInt();
DbRoomID = Sc.nextInt();
if (days <= 7)
{
if (DbFloor == this.Floor && DbRoomID == this.RoomID)
{
int DbcidDay = Dbcid/10000;
int DbcidMonth = (Dbcid/100)%100;
int DbcodDay = Dbcod/10000;
if(ciMonth == DbcidMonth)
{
if (ciDay >= DbcidDay && ciDay < DbcodDay)
{
check = 2;
}
else if (coDay >= DbcidDay && coDay < DbcodDay)
{
check = 3;
}
else if (ciDay <= DbcidDay && coDay >= DbcodDay)
{
check = 4;
}
else
{
check = 1;
}
}
else
{
check = 1;
}
}
else
{
check =1;
}
}
else
{
check =5;
}
}
if(check > 0)
{
Sc.close();
Reader.close();
Fr.close();
}
}
catch (Exception e)
{
}
return check;
}
There are a few issues I can see:
You need to close your streams in a finally clause (or, better still, use a try-with-resource). Otherwise, if an exception is thrown that interrupts the normal program flow, your stream will not be closed immediately.
You should only close the outermost stream object (so e.g. your BufferedReader, but not the FileReader)
You are swallowing exceptions. At least do a printStackTrace() on the exceptions you catch so you can see if any are actually thrown.
Avoid methods like File.delete() that don't throw exceptions in the case of an error. Instead, use the equivalent methods on the Files.class, which throw exceptions in the event of an error.
Incidentally, although it's not an issue as such, you don't need to call flush() just before close()-- the latter automatically flushes before closing.

How to search and remove some values from xml java

I have an xml abc.xml
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<mes:SomeRq>
<RqID>?</RqID>
<MsgRqHdr>
....
</mes:SomeRq>
</soapenv:Body>
</soapenv:Envelope>
Is there a way i can search mes:, from this xml and replace it with ins:
Thanks in advance.
public static void findreplcae(String strFilePath) throws IOException {
String currentString = "mes:";
String changedString = "ins:";
BufferedReader reader = new BufferedReader(new FileReader(strFilePath));
StringBuffer currentLine = new StringBuffer();
String currentLineIn;
while ((currentLineIn = reader.readLine()) != null) {
System.out.println(currentLineIn);
boolean bool = false;
String trimmedLine = currentLineIn.trim();
System.out.println(trimmedLine);
if (trimmedLine.contains(currentString)) {
trimmedLine.replace(currentString, changedString);
bool = true;
if (bool != true) {
currentLine = currentLine.append(currentLineIn + System.getProperty("line.separator"));
}
}
reader.close();
BufferedWriter writer = new BufferedWriter(new FileWriter(strFilePath));
writer.write(currentLine.toString());
writer.close();
}
}
It's not good idea to parse it as a text file. DocumentBuilder.parse to parse the file, call getDocumentElement() and check for getPrefix. If it matches, replace with setPrefix(). Note you have to register prefix if not yet done already.
Check this page for tutorial.
Some issues:
trimmedLine.replace(currentString, changedString);, the result is returned, so you have to store it somewhere. See here
What is this supposed to do?
bool = true;
if (bool != true) {
currentLine = currentLine.append(currentLineIn + System.getProperty("line.separator"));
}
Don't close the reader while reading in a loop.
If you want to overwrite the original file, this should do (although I am not sure, if you really want to trim the lines):
String currentString = "mes:";
String changedString = "ins:";
try {
BufferedReader reader = new BufferedReader(new FileReader(strFilePath));
StringBuffer newContents = new StringBuffer();
String currentLineIn = null;
while ((currentLineIn = reader.readLine()) != null) {
String trimmedLine = currentLineIn.trim();
if (trimmedLine.contains(currentString)) {
newContents.append(trimmedLine.replace(currentString, changedString));
}
else {
newContents.append(trimmedLine);
}
newContents.append(System.getProperty("line.separator"));
}
reader.close();
BufferedWriter writer = new BufferedWriter(new FileWriter(strFilePath));
writer.write(newContents.toString());
writer.close();
} catch (IOException e) {
// TODO handle it
}

Comparing two files in java

I am trying to compare two .txt files (i.e their contents), but when I execute this code my application goes into an infinite loop. Why?
public int compareFile(String fILE_ONE2, String fILE_TWO2)throws Exception
{
File f1 = new File(fILE_ONE2); //OUTFILE
File f2 = new File(fILE_TWO2); //INPUT
FileReader fR1 = new FileReader(f1);
FileReader fR2 = new FileReader(f2);
BufferedReader reader1 = new BufferedReader(fR1);
BufferedReader reader2 = new BufferedReader(fR2);
String line1 = null;
String line2 = null;
int flag=1;
while ((flag==1) &&((line1 = reader1.readLine()) != null)&&((line2 = reader2.readLine()) != null))
{
if (!line1.equalsIgnoreCase(line2))
flag=0;
else
flag=1;
}
reader1.close();
reader2.close();
return flag;
}
I converted your code into a main program. There is no infinite loop in this code.
I am assuming you are comparing 2 text files of a small-ish size.
import java.io.*;
public class Diff {
public static void main(String[] args) throws FileNotFoundException, IOException {
File f1 = new File(args[0]);// OUTFILE
File f2 = new File(args[1]);// INPUT
FileReader fR1 = new FileReader(f1);
FileReader fR2 = new FileReader(f2);
BufferedReader reader1 = new BufferedReader(fR1);
BufferedReader reader2 = new BufferedReader(fR2);
String line1 = null;
String line2 = null;
int flag = 1;
while ((flag == 1) && ((line1 = reader1.readLine()) != null)
&& ((line2 = reader2.readLine()) != null)) {
if (!line1.equalsIgnoreCase(line2))
flag = 0;
}
reader1.close();
reader2.close();
System.out.println("Flag " + flag);
}
}
I ran it on 2 small different text files. This is the output.
javac Diff.java && java Diff a.txt b.txt
Flag 0
If you think you have an infinite loop, the issue might be elsewhere.
The code looks good, no infinite loops. You can remove irrespective check in the code and can update the code as below:
int flag=1;
while (((line1 = reader1.readLine()) != null)&&((line2 = reader2.readLine()) != null))
{
if (!line1.equalsIgnoreCase(line2))
{
flag=0;
break;
}
}
As the return type of the method is integer than it will return 0 if different and 1 if equal.
Assuming text file inputs, an alternative implementation to the while loop:
while (true) // Continue while there are equal lines
{
line1 = reader1.readLine();
line2 = reader2.readLine();
if (line1 == null) // End of file 1
{
return (line2 == null ? 1 : 0); // Equal only if file 2 also ended
}
else if (line2 == null)
{
return 0; // File 2 ended before file 1, so not equal
}
else if (!line1.equalsIgnoreCase(line2)) // Non-null and different lines
{
return 0;
}
// Non-null and equal lines, continue until the input is exhausted
}
The first else if is not necessary, but it is included for clarity purposes. Otherwise, the above code could be simplified to:
while (true) // Continue while there are equal lines
{
line1 = reader1.readLine();
line2 = reader2.readLine();
if (line1 == null) // End of file 1
{
return (line2 == null ? 1 : 0); // Equal only if file 2 also ended
}
if (!line1.equalsIgnoreCase(line2)) // Different lines, or end of file 2
{
return 0;
}
}
The loop should be placed in a try/finally block, to assure that the readers are closed.
Above method by Jess will fail if file2 is same as file1 but has an extra line at the end.
This should work.
public boolean compareTwoFiles(String file1Path, String file2Path)
throws IOException {
File file1 = new File(file1Path);
File file2 = new File(file2Path);
BufferedReader br1 = new BufferedReader(new FileReader(file1));
BufferedReader br2 = new BufferedReader(new FileReader(file2));
String thisLine = null;
String thatLine = null;
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
while ((thisLine = br1.readLine()) != null) {
list1.add(thisLine);
}
while ((thatLine = br2.readLine()) != null) {
list2.add(thatLine);
}
br1.close();
br2.close();
return list1.equals(list2);
}
if you use java8, the code below to compare file contents
public boolean compareTwoFiles(String file1Path, String file2Path){
Path p1 = Paths.get(file1Path);
Path p1 = Paths.get(file1Path);
try{
List<String> listF1 = Files.readAllLines(p1);
List<String> listF2 = Files.readAllLines(p2);
return listF1.containsAll(listF2);
}catch(IOException ie) {
ie.getMessage();
}
}

Take Strings from Text file and assign each line to value (2 at a time and insert into LinkedHashMap)

What I'm trying to do is, load a Text file, then take the values from each line and assign them to a variable in my program. Every two lines, I will insert them into a LinkedHashMap (As a pair)
The problem with a buffered reader is, all I can seem to do is, read one line at a time.
Here is my current code:
public static void receiver(String firstArg) {// Receives
// Input
// File
String cipherText;
String key;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
// File in = new File(inFile);
try (InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(
new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
// System.out.println(line);
String[] arrayLine = line.split("\n"); // here you are
// splitting
// with whitespace
cipherText = arrayLine[0];
// key = arrayLine[1];
System.out.println(arrayLine[0] + " " + arrayLine[1]);
cipherKeyPairs.put(arrayLine[0], arrayLine[1]);
}
} catch (IOException x) {
System.err.println(x);
}
The problem is, it can't find the arrayLine[1] (for obvious reasons). I need it to read two lines at a time without the array going out of bounds.
Any idea how to do this, so that I can store them into my LinkedHashMap, two lines at a time as separate values.
You can overcome this issue by inserting in the List every 2 lines reading.
A description for this code is that: "Bold is the true case"
Read the first line (count is 0)
If (secondLine is false) ==> Save the line to CipherText variable, make secondLine = true
Else If (secondLine is true) ==> Add to list (CipherText, line), make secondLine = false
Read the second line (count is 1)
If (secondLine is false) ==> Save the line to CipherText variable, make secondLine = true
Else If (secondLine is true) ==> Add to list (CipherText, line), make secondLine = false
String cipherText;
boolean secondLine = false;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
try {
InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
if (!secondLine) //first line reading
{
cipherText = line;
secondLine = true;
}
else if (secondLine) //second line reading
{
cipherKeyPairs.put(cipherText, line);
secondLine = false;
}
}
} catch (IOException x) {
System.err.println(x);
}
See if this works for you. I just edited your code. it might not be the best answer.
public static void receiver(String firstArg) {// Receives
// Input
// File
String cipherText;
String key;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
// File in = new File(inFile);
try (InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(
new InputStreamReader(in))) {
String line = null;
List<String> lines = new ArrayList();
while ((line = reader.readLine()) != null) {
lines.add(line);//trim line first though and check for empty string
}
for(int i=1;i<lines.size();i++){
cipherText = arrayLine[i];
// key = arrayLine[1];
System.out.println(arrayLine[i] + " " + arrayLine[i-1]);
cipherKeyPairs.put(arrayLine[i-1], arrayLine[i]);
}
} catch (IOException x) {
System.err.println(x);
}
}

find specific string after certain pattern in a txt file

so i am new to java.please offer some sample codes if possible.
The situation is i have a html format in a text file. i need to read the file and find the string after a pattern which is 'data-name'. i need to find every string after the "data-name" through the entire text file. i did some research online . i already used html parser to get the html and store it in a text file. i know i might need to use regular expression. so please help me. Thank you guys!
below is my code for getting the html. the result is concatenated.
public static void main(String[] args) {
try {
URL url = new URL("https://twitter.com/search?q=%23JENOSMROOKIESOPENFOLBACK&src=tren");
// read text returned by server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
PrintWriter out = new PrintWriter(new FileWriter("C:/Users/Desktop/htmlsourcecode.txt"));
while ((line = in.readLine()) != null) {
System.out.println(line);
out.print(line);
}
out.close();
}
How about something like this
// External resource(s).
BufferedReader in = null;
PrintWriter out = null;
try {
URL url = new URL(
"https://twitter.com/search?q=%23JENOSMROOKIESOPENFOLBACK&src=tren");
// read text returned by server
in = new BufferedReader(new InputStreamReader(
url.openStream()));
String line;
// out = new PrintWriter(new FileWriter(
// "htmlsourcecode.txt"));
final String DATA_NAME = "data-name=\"";
while ((line = in.readLine()) != null) {
int pos1 = line.indexOf(DATA_NAME); // opening position.
if (pos1 > -1) { // did we match?
// Add the length of the string.
pos1 += DATA_NAME.length();
// find the closing quote.
int pos2 = line.indexOf("\"", pos1 + 1);
if (pos2 > -1) {
String dataName = line.substring(pos1,
pos2);
System.out.println(dataName);
// out.print(line);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// Close external resource(s).
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
out.close();
}
}

Categories

Resources