After been deleted manually, the file content can still be read out? - java

import java.io.FileReader;
public class SimpoTest {
public static void main(String[] args) {
FileReader fileReader = null;
try {
fileReader = new FileReader("/home/brian/Desktop/me");
int read = fileReader.read();
System.out.println((char) read);
} catch (Exception e) {
fileReader = null;
e.printStackTrace();
}
}
}
1\ echo "1" > /home/brian/Desktop/me
2\ set the breakpoint to "int read = fileReader.read();"
3\ start the debug
4\ rm -f /home/brian/Desktop/me
5\ jump to the end <======== the "1" still outputted on the console...
well...this is really weird to me. as i though there should be an exception thrown out.
can anyone give any explanation?
any comments or suggestions are appreciated.

On most Unix-like systems, a file's data remains on disk until all references go away; this includes both pathnames (hard links) and open file handles.

This is expected behavior at least on a unix-like operating system: as long as there's an open file descriptor to it, the rm'd file's blocks will remain allocated and accessible via that file descriptor.
I expect you cannot, however, open a new file descriptor to them by means of the deleted filename.

Related

input from file in java

I am java beginner learner and i am trying to output the data on file which i call a.txt. need help i have no idea y i am getting exception error file not open . i put a.txt in the same directory in which i have main and readfile.
- main path : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
- readfile : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
- a.txt : C:\Users\Navdeep\Desktop\java\assign1\src\assign1
Thanks in advance .
main.java
package assign1;
public class main {
public static void main(String[] args) {
readfile r = new readfile();
r.openFile();
r.readFile();
r.closeFile();
}
}
readile.java
package assign1;
import java.io.*;
import java.util.*;
public class readfile {
private Scanner x;
public void openFile() {
try {
x = new Scanner(new File("a.txt"));
} catch (Exception e) {
System.out.println("file not open \n");
}
}
public void readFile() {
while (x.hasNext()) {
String Agent = x.next();
String request_type = x.next();
String classtype = x.next();
String numberofseat = x.next();
String arrivaltime = x.next();
System.out.printf("%s %s %s %s %s \n", Agent,
request_type, classtype, numberofseat, arrivaltime);
}
}
public void closeFile() {
x.close();
}
}
a.txt
1 r e 1 0
2 r e 1 1
If you use a File with a relative path, it is assumed relative to the "current user directory". What's the "current user directory"? See the doc:
A relative pathname, in contrast, must be interpreted in terms of information taken from some other pathname. By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.
Also from the doc:
On UNIX systems, a relative pathname is made absolute by resolving it against the current user directory. On Microsoft Windows systems, a relative pathname is made absolute by resolving it against the current directory of the drive named by the pathname, if any; if not, it is resolved against the current user directory.
So one way to get the File to be found using a relative path would be to start the JVM in the directory with the file.
However, this approach can be kind of limiting since it constrains you to always start the JVM in a certain directory.
As an alternative, you might consider using ClassLoader#getResourceAsStream. This allows you to load any resource that is on the JVM's "classpath". The classpath can be configured in a number of different ways, including at launch time using arguments to the JVM. So I would suggest using that, rather than initializing your Scanner with a File. This would look like:
InputStream is = StackOverflow.class.getClassLoader().getResourceAsStream("a.txt");
Scanner scanner = new Scanner(is);
Now, when using getResourceAsStream, you have to make sure that the file referenced is on the classpath of the Java Virtual Machine process which holds your program.
You've said in comments that you're using Eclipse.
In Eclipse, you can set the classpath for an execution by doing the following:
1) After running the program at least once, click on the little dropdown arrow next to the bug or the play sign.
2) Click on "Debug configurations" or "Run Configurations".
3) In the left sidebar, select the run configuration named after the program you're running
4) Click on the "Classpath" tab
5) Click on "User Entries"
6) Click on "Advanced"
7) Select "Add Folders"
8) Select the folder where a.txt resides.
Once you have done this, you can run the program using the run configuration you have just set up, and a.txt will be found.
Basic idea of classpath
The classpath represents the resources that the JVM (Java Virtual Machine) holding your program knows about while it's running. If you are familiar with working from a command line, you can think of it as analogous to your OS's "PATH" environment variable.
You can read about it in depth here.
Instead of putting the file in src folder put the txt file in the project ie outside the src.
Here is one using BufferedReader.
public static void main(String[] args) {
// check for arguments. this expects only one argument #index [0]
if (args.length < 1) {
System.out.println("Please Specify your file");
System.exit(0);
}
// Found atleast one argument
FileReader reader = null;
BufferedReader bufferedReader = null;
// Prefer using a buffered reader depending on size of your file
try {
reader = new FileReader(new File(args[0]));
bufferedReader = new BufferedReader(reader);
StringBuilder content = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null)
content.append(line);
System.out.println(content.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
// dont forget to close your streams
try {
if (bufferedReader != null)
bufferedReader.close();
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Let me know if you have any isues.
Good_luck_programming!

Check if file exists from string

This is the code I use when I try to read some specific text in a *.txt file:
public void readFromFile(String filename, JTable table) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String a,b,c,d;
for(int i=0; i<3; i++)
{
a = bufferedReader.readLine();
b = bufferedReader.readLine();
c = bufferedReader.readLine();
d = bufferedReader.readLine();
table.setValueAt(a, i, 0);
table.setValueAt(b, i, 1);
table.setValueAt(c, i, 2);
table.setValueAt(d, i, 3);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the reader
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And it is called in this way:
readFromFile("C:/data/datafile.txt", table1)
The problem is the following: the 1st time I open the program the *.txt file I'm going to read does not exist, so I thought I could use the function exists(). I have no idea about what to do, but I tried this:
if(("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1)
}
It is not working because NetBeans gives me a lot of errors. How could I fix this?
String has no method named exists() (and even if it did it would not do what you require), which will be the cause of the errors reported by the IDE.
Create an instance of File and invoke exists() on the File instance:
if (new File("C:/data/datafile.txt").exists())
{
}
Note: This answer use classes that aren't available on a version less than Java 7.
The method exists() for the object String doesn't exist. See the String documentation for more information. If you want to check if a file exist base on a path you should use Path with Files to verify the existence of the file.
Path file = Paths.get("C:/data/datafile.txt");
if(Files.exists(file)){
//your code here
}
Some tutorial about the Path class : Oracle tutorial
And a blog post about How to manipulate files in Java 7
Suggestion for your code:
I'll point to you the tutorial about try-with-resources as it could be useful to you. I also want to bring your attention on Files#readAllLines as it could help you reduce the code for the reading operation. Based on this method you could use a for-each loop to add all the lines of the file on your JTable.
you can use this code to check if the file exist
Using java.io.File
File f = new File(filePathString);
if(f.exists()) { /* do something */ }
You need to give it an actual File object. You're on the right track, but NetBeans (and java, for that matter) has no idea what '("C:/data/datafile.txt")' is.
What you probably wanted to do there was create a java.io.File object using that string as the argument, like so:
File file = new File ("C:/data/datafile.txt");
if (file.exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
Also, you were missing a semicolon at the end of the readFromFile call. Im not sure if that is just a typo, but you'll want to check on that as well.
If you know you're only ever using this File object just to check existence, you could also do:
if (new File("C:/data/datafile.txt").exists()) {
readFromFile("C:/data/datafile.txt", table1);
}
If you want to ensure that you can read from the file, it might even be appropriate to use:
if(new File("C:/data/datafile.txt").canRead()){
...
}
as a condition, in order to verify that the file exists and you have sufficient permissions to read from the file.
Link to canRead() javadoc

How to write content to a file

try {
File file = new File("sample.txt");
FileWriter fw = new FileWriter(file,true);
fw.append('d');
fw.write(100);
fw.close();
} catch(IOException exp) {
exp.printStackTrace();
}
I am unable to append or write anything to the file.
But I could read the content from the file.
Is anything wrong with my code?
It sounds like you probably are writing to a file - but not the file you expect to. If no exceptions have been thrown (and swallowing an exception, just writing it to standard out, is rarely the right approach) then the file will exist somewhere.
It will be in whatever directory the code is running from - which may well not be the same as the directory containing the sample.txt file you're reading. I suggest you explore the file system, and also check the Run Configuration in Eclipse to see what the working directory for the app will be.
As an aside, you should be closing the writer in a finally block so that it gets closed even if there's an exception, like this:
File file = new File("sample.txt");
FileWriter fw = null;
try {
fw = new FileWriter(file, true);
fw.append('d');
fw.write(100);
} catch(IOException) {
// Ideally do something to indicate the failure to the caller
// - do you need to catch this at all?
e.printStackTrace();
} finally {
// From Guava
Closeables.closeQuietly(fw);
}
Obviously you can do this without Guava but it'll make things a lot simpler - and not just here. If you're using Java 7 you can make it even simpler with a try-with-resources statement.
http://www.roseindia.net/java/example/java/io/java-write-to-file.shtml
You can Flush context if code is right and still you are facing problem. it "Flushes the stream"
This link can help!
Like was said before the file may be getting cleared out during the build/clean process. Try specificing an absolute path to the file and running it again. Everything you have written is correct sans the corrections already offered.
try {
File file = new File("C:\sample.txt"); // for Windows or possibly just "/sample.txt" for *nix
FileWriter fw = new FileWriter(file,true);
fw.append('d');
fw.write(100);
} catch(IOException e) {
e.printStackTrace();
} finally {
// Good practice to move close to a finally block
fw.close();
}
You may try using the below syntax :
String filename = "C:/sample.txt";
FileWriter fw = new FileWriter(filename,true);

Java desktop app cannot write a file on C:\ drive

I am trying to write a file on a C:\ drive, but I get an exception.
java.io.IOException: Access denied.
Code:
public class Test {
public static void main(String[] args) {
try {
StringBuilder sb = new StringBuilder(File.separator);
sb.append("index.txt");
// sb is "\\index.txt"
File f = new File(sb.toString());
boolean isCreated = f.createNewFile();
System.out.println(isCreated);
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Actually, I get it, I don't have permission to write a file there, but I am quite sure it can be done somehow. If I had an applet, I'd just obtain a permission, but here, I don't know how to do it.
The probable solution may be checking if I can write a file there, but to check it I might try to write a file first adn then delete it in order to check if it is possible to write a file there, but I don't find this solution an optimal way.
The easiest way to check is to use File.canWrite().
Having said that, it looks like you're writing into the root of the drive. On Windows that's probably not a good idea, and you may want to consider writing elsewhere - e.g. a temp dir.
I have written a method, that takes a String to a directory, and checks, whether you can write a file out there:
static boolean canWrite(String folderPath) {
File file = new File(folderPath);
String new_file = "HastaLaVistaBaby";
if (file.isDirectory()) {
try {
new File(file + "\\" + new_file).createNewFile();
} catch (IOException e) {
return false;
}
new File(file + "\\" + new_file).delete();
return true;
} else {
return false;
}
}
To improve it, you may check, whether file.isFile() and get a parent directory and call this method.
This line should be:
sb.append("C:\\index.txt");
The extra backslash escapes a backslash.
Whether you hard-code a file name, like I did, or you get a file name from the user, you need the full path and file name.

FFMPEG in Java issue

I have the following code in a java Web Service:
public boolean makeFile(String fileName, String audio)
{
if (makeUserFolder())
{
File file = new File(getUserFolderPath() + fileName + amr);
FileOutputStream fileOutputStream = null;
try
{
file.createNewFile();
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(Base64.decode(audio));
return true;
}
catch(FileNotFoundException ex)
{
return false;
}
catch(IOException ex)
{
return false;
}
finally{
try {
fileOutputStream.close();
convertFile(fileName);
} catch (IOException ex) {
Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
else
return false;
}
public boolean convertFile(String fileName)
{
Process ffmpeg;
String filePath = this.userFolderPath + fileName;
try {
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",filePath + amr,filePath + mp3);
pb.redirectErrorStream();
ffmpeg = pb.start();
} catch (IOException ex) {
return false;
}
return true;
}
It used to work and now it simply won't execute the ffmpeg conversion for some reason. I thought it was a problem with my file but after running the command from terminal no errors are thrown or anything, thought it was maybe permissions issue but all the permissions have been granted in the folder I'm saving the files. I noticed that the input BufferedReader ins being set to null after running the process, any idea what's happening?
First of all, a small nitpick with your code...when you create the FileOutputStream you create it using a string rather than a File, when you have already created the File before, so you might as well recycle that rather than force the FileOutputStream to instantiate the File itself.
Another small nitpick is the fact that when you are writing out the audio file, you should enclose that in a try block and close the output stream in a finally block. If you are allowed to add a new library to your project, you might use Guava which has a method Files.write(byte[],File), which will take care of all the dirty resource management for you.
The only thing that I can see that looks like a definite bug is the fact that you are ignoring the error stream of ffmpeg. If you are blocking waiting for input on the stdout of ffmpeg, then it will not work.
The easiest way to take care of this bug is to use ProcessBuilder instead of Runtime.
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",filePath+amr,filePath+mp3);
pb.redirectErrorStream(); // This will make both stdout and stderr be redirected to process.getInputStream();
ffmpeg = pb.start();
If you start it this way, then your current code will be able to read both input streams fully. It is possible that the stderr was hiding some error that you were not able to see due to not reading it.
If that was not your problem, I would recommend using absolute paths with ffmpeg...in other words:
String lastdot = file.getName().lastIndexOf('.');
File mp3file = new File(file.getParentFile(),file.getName().substring(0,lastdot)+".mp3");
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",file.getAbsolutePath(),mp3file.getAbsolutePath());
// ...
If that doesn't work, I would change ffmpeg to be an absolute path as well (in order to rule out path issues).
Edit: Further suggestions.
I would personally refactor the writing code into its own method, so that you can use it elsewhere necessary. In other other words:
public static boolean write(byte[] content, File to) {
FileOutputStream fos = new FileOutputStream(to);
try {
fos.write(content);
} catch (IOException io) {
// logging code here
return false;
} finally {
closeQuietly(fos);
}
return true;
}
public static void closeQuietly(Closeable toClose) {
if ( toClose == null ) { return; }
try {
toClose.close();
} catch (IOException e) {
// logging code here
}
}
The reason that I made the closeQuietly(Closeable) method is due to the fact that if you do not close it in that way, there is a possibility that an exception will be thrown by the close() method, and that exception will obscure the exception that was thrown originally. If you put these in a utility class (although looking at your code, I assume that the class that it is currently in is named FileUtils), then you will be able to use them throughout your application whenever you need to deal with file output.
This will allow you to rewrite the block as:
File file = new File(getUserFolderPath() + fileName + amr);
file.createNewFile()
write(Base64.decode(audio),file);
convertFile(fileName);
I don't know whether or not you should do this, however if you want to be sure that the ffmpeg process has completed, then you should say ffmpeg.waitFor(); to be sure that it has completed. If you do that, then you should examine ffmpeg.exitValue(); to make sure that it completed successfully.
Another thing that you might want to do is once it has completed, write what it output to a log file so you have a record of what happened, just in case something happens.

Categories

Resources