New file not getting called on renameTo() - java

I used the following code to edit the file OIMV2Migration.sh on linux.
String oldFileName = "OIMV2Migration.sh";//file to be edited
String tmpFileName = "tmp_try.dat"; //new file containing changes
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(oldFileName));
bw = new BufferedWriter(new FileWriter(tmpFileName));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("SURBHI")) {
line = line.replace("SURBHI MITTAL" , "SURBHI GUPTA");}
bw.write(line+"\n");
}
} catch (Exception e) {
return;
} finally {
try {
if(br != null)
br.close();
} catch (IOException e) {
//
}
try {
if(bw != null)
bw.close();
} catch (IOException e) {
//
}}
//delete the old file
File oldFile = new File(oldFileName);;
oldFile.delete();
//rename the new file to old file
File newFile = new File(tmpFileName);
System.out.println(newFile.getAbsolutePath());
Boolean success = newFile.renameTo(oldFile);
System.out.println(newFile.getAbsolutePath());
Here , the file is getting updated correctly , but the absolute path of the newFile is always pointing to "tmp_try.dat , both before renameTo() and after renameTo() is executed.
I got to know from stack overflow link that the absolute path of the file instance does not change , it remains same.
But my problem is there is another file in my system idmlcm.sh which is internally calling OIMV2Migration.sh.But after this method is executed , idmlcm.sh is not able to call OIMV2Migration.sh as if it cant find this file.
Although the file exists in the correct directory only.

According to JAVA Documentation
Behavior of renameTo :
Many aspects of the behavior of this method are inherently
platform-dependent: The rename operation might not be able to move a
file from one filesystem to another, it might not be atomic, and it
might not succeed if a file with the destination abstract pathname
already exists. The return value should always be checked to make sure
that the rename operation was successful.
In your case, first you are deleting oldFile and than rename that tmpFile to oldFileName, that actually works perfect, but when you call newFile.getAbsolutePath() will print path of tmpFile because the Object newFile still refers to old path only. You need to re-create the File Object to access your renamed File.

Related

FileNotFound exception but there is a file (Java Eclipse)

I cant get rid of this FileNotFound error even though the file exists. Any ideas? (There are hundreds of lines of code so im just going to paste the chunk around the error, if this is an issue I can post more)
// method start
System.out.println(System.getProperty("user.dir"));
File names = new File("src/guiProject/nameList");
System.out.println(names.getAbsolutePath());
// !!!! V ERROR OCCURS HERE V !!!!
BufferedReader br = new BufferedReader(new FileReader(names));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
String allNames = sb.toString();
userListArea.setText(allNames);
} catch (IOException o) {
o.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
//method end
Probably your Windows does not show file extensions; nameList.txt?
Otherwise the working directory is not in the project directory with subdirectory src.
A FileReader uses the default Charset, so the file is not portable. If you run the application on another platform then the developer's, the encoding is wrong.
Best use UTF-8, full Unicode.
Then the reading strips the line ending:
while (line != null) {
sb.append(line).append("\r\n");
line = br.readLine();
}
You could do:
Path names = Paths.get("src/guiProject/nameList.txt"); // File
Path names = Paths.get(
MyClass.class.getResource("/guiProject/nameList.txt").toURI()); // Resource
String allNames = new String(Files.readAllBytes(names), StandardCharsets.UTF_8);
userListArea.setText(allNames);
If it is a read-only file, stored in the application jar, it is a resource rather than a disk File.
Maybe you are not in the folder you think.
Create a file with a dummy name and get the absolute path of this file, this way you can doublecheck you are where you think you really are.

BufferedReader/FileReader is not finding path correctly even with try/catch

I am trying to read from a text file using BufferedReader and FileReader and I am constantly running into this problem:
java.io.FileNotFoundException: dicomTagList.txt (The system cannot find the file specified)C:\temp\workspace\DICOMVALIDATE\dicomTagList.txt
I can't seem to find out why this is occurring when I have that file in the correct directory and was able to even verify it with getAbsolutePath() Method in FileReader.
Can anyone advise why this may be?
Here is my code snippet:
public void readFromTextFile(File path) throws IOException
{
try
{
System.out.println(dicomList.getAbsolutePath());
String line;
BufferedReader bReader = new BufferedReader(new FileReader(dicomList));
while( (line = bReader.readLine()) != null)
{
System.out.println(line);
}
bReader.close();
}
catch(FileNotFoundException e)
{
System.err.print(e);
}
catch(IOException i)
{
System.err.print(i);
}
}
Are you sure that the file really exists? What will the following expression print:
dicomList.exists();
In Java java.io.File is representing just a path to a file, not necessarily a real file. This means you can create File object even if the underlying path does not exist.

how to get a conf.txt path in eclipse

I have an eclipse project and in one folder there is a text file "conf.txt". I can read and write the file when I use the path on my Computer. But I have to write my own folders there as well, not only the workspace folders.
So know I want to commit the program for others, but then the path I put in the program won't work, because the program is running on a different computer.
What I need is to be able to use the file with only the path in my workspace.
If I just put in the path, which is in the workspace it won't work.
This is how my class File looks like.
public class FileUtil {
public String readTextFile(String fileName) {
String returnValue = "";
FileReader file = null;
try {
file = new FileReader(fileName);
BufferedReader reader = new BufferedReader(file);
String line = "";
while ((line = reader.readLine()) != null) {
returnValue += line + "\n";
}
reader.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
return returnValue;
}
public void writeTextFile(String fileName, String s) throws IOException {
BufferedWriter output = new BufferedWriter(new FileWriter(fileName));
try {
output.write(s);
}
finally {
output.close();
}
}
}
I hope someone knows what to do.
Thanks!
I am not sure but I attached the screen shot with little bit explanation. Let me know if you have any question.
Your project is root folder here and images as resources folder from where you can access the file using relative path.
// looks for file in root --> file.txt
scan = new Scanner((new File("file.txt")));
// looks for file in given relative path i.e. root--> images--> file.txt
scan = new Scanner((new File("images/file.txt")));
If you want your configuration file to be accessed through a relative path, you shouldn't need to add anything to the front of it. Assuming you're using a bufferedReader, or something of the sort it would look as simple as: br = new BufferedReader(new FileReader("config.txt"));
This will cause a search of the runtime directory, making it so you don't have to fully qualify the path to your file. That being said you have to ensure your config.txt is within the same directory as your executable.

Cannot delete file Java

I have this method that gets the last line of a .txt file and creates a new temp file without that line. But when I try to delete the .txt that has the line I want to delete (so then I can rename the temp file) for some reason I can't. This is the code:
void removeFromLocal() throws IOException {
String lineToRemove = getLastLine();
File inputFile = new File("nexLog.txt");
File tempFile = new File("TempnexLog.txt");
BufferedReader reader = null;
BufferedWriter writer = null;
try {
reader = new BufferedReader(new FileReader(inputFile));
writer = new BufferedWriter(new FileWriter(tempFile));
String currentLine;
int i = 0;
while ((currentLine = reader.readLine()) != null) {
i++;
String trimmedLine = currentLine.trim();
if (!trimmedLine.equals(lineToRemove)) {
if (i != 1) {
writer.newLine();
}
writer.write(currentLine);
}
}
reader.close();
reader = null;
writer.flush();
writer.close();
writer = null;
System.gc();
inputFile.setWritable(true);
if (!inputFile.delete()) {
System.out.println("Could not delete file");
return;
}
if (!tempFile.renameTo(inputFile)) {
System.out.println("Could not rename file");
}
//boolean successful = tempFile.renameTo(inputFile);
} catch (IOException ex) {
Logger.getLogger(dropLog.class.getName()).log(Level.SEVERE, null, ex);
}
}
Whats funny is that when I press the button that calls the method once, nothing happens ("Could not delete file"), the second time it works fine and the 3rd I get "Could not rename file".
The file cannot be deleted when it's been opened by another process. E.g. in notepad or so or maybe even another FileReader/FileWriter on the file somewhere else in your code. Also, when you're executing this inside an IDE, you'll risk that the IDE will touch the file during the background scan for modifications in the project's folder. Rather store the files in an absolute path outside the IDE's project.
Also, the code flow of opening and closing the files has to be modified so that the close is performed in the finally block. The idiom is like this:
Reader reader = null;
try {
reader = new SomeReader(file);
// ...
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
Or, if you're already on Java 7, use the automatic resource management instead.
try (Reader reader = new SomeReader(file)) {
// ...
}
Further I recommend to use File#createTempFile() instead to create temp files. This way an unique temp filename will be generated and thus you prevent the very same temp file being written and renamed by multiple processes.
File tempFile = File.createTempFile("nexLog", ".txt");
Does BufferedReader close the nested reader (not mentioned in the doc)? You have to make sure, by checking if setWritable was successful.Otherwise you need to close FileReader too, and I would recommend because in case you close it twice there is no harm... by the way GC call is more harmful than useful.

Test if file exists

I'm trying to open a file in android like this :
try
{
FileInputStream fIn = context.openFileInput(FILE);
DataInputStream in = new DataInputStream(fIn);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
if(in!=null)
in.close();
}
catch(Exception e)
{ }
, but in case the file does not exists a file not found exception is thrown . I'd like to know how could I test if the file exists before attempting to open it.
I think the best way to know if a file exists, without actually trying to open it, is as follows:
File file = getContext().getFileStreamPath(FILE_NAME);
if(file.exists()) ...
The documentation says Context.openFileInput either returns an inputStream (file found) or throws a FileNotFoundException (not found)
http://developer.android.com/reference/android/content/Context.html#openFileInput(java.lang.String)
So it looks like the exception is your "test".
You could also try using standard
java.io.File file = new java.io.File(PATHTOYOURCONTEXT , FILE);
if (file.exists()) {
FileInputStream fIn = new FileInputStream(file);
}
But that is not recommended. Context.openFileInput() and Context.openFileOutput() make sure you stay in your applications storage context on the device, and that all of your files get
deleted when your app gets uninstalled.
With the standard java.io.File this is the function I have created, and works correctly:
private static final String APP_SD_PATH = "/Android/data/com.pkg.myPackage";
...
public boolean fileExistsInSD(String sFileName){
String sFolder = Environment.getExternalStorageDirectory().toString() +
APP_SD_PATH + "/Myfolder";
String sFile=sFolder+"/"+sFileName;
java.io.File file = new java.io.File(sFile);
return file.exists();
}
why dont you just catch the FileNotFound exception and take that as the file not being present.
If you want to ensure a file exists (i.e. if it doesn't exist create a new one, if it does then don't erase it) then use File.createNewFile:
https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()
e.g.
{
String pathName = <file path name>
File file = new File (pathName);
Uri pathURI = Uri.fromFile (file);
boolean created;
String mIOException = "";
String mSecException = "";
try
{
created = file.createNewFile();
if (created)
{
ctxt.sendBroadcast (new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, pathURI));
}
}
catch (IOException ioex)
{
mIOException = ioex.getMessage();
}
catch (SecurityException sex)
{
mSecException = sex.getMessage();
}
}
If you want to open a file in any case (i.e. if it doesn't exist create a new one, if it does append to the old one) you can use this, no testing necessary:
public static void write_custom_log(String message){
File root = Environment.getExternalStorageDirectory();
try{
BufferedWriter fw = new BufferedWriter(new FileWriter(new File("/mnt/sdcard/tjb_tests/tjb_log_file.txt"),true));
if (root.canWrite()){
fw.write(message);
fw.close();
}
} catch (IOException e) {
Log.e("One", "Could not write file " + e.getMessage());
}
}
My suggestion is to check length of the file. if file.length() returns 0 that means file doesn't exist.

Categories