Should a File be created explicitly when creating a stream? - java

I was wondering about a property of Java's FileInputStreams (and FileOutputStreams as well). When creating them you can use either of these constructors:
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file) throws FileNotFoundException
I often see (and write) code like this:
InputStream in = new FileInputStream(new File("data.txt"));
You can see I create a File there. I could also do it without it:
InputStream in = new FileInputStream("data.txt");
By the JDK source code there seems to be next to no difference between how they work. Here is the source for the constructor that takes String:
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
All of this is basically the same for FileOutputStream.
Is using either one of the constructors a convention I don't know of, and are there any benefits to either? Is it a different case with FileInputStream or FileOutputStream?

Although, the first constructor FileInputStream(String name) is probably used more often, it is only the second one, which is FileInputStream(File file), which allows for accurate checking of the input file using the File class methods before we link it with the InputStream.
Furthermore, the process of creating an object of FileOutputStream class is not dependent on the existence or possible lack of the appropriate file. When you create an object of FileOutputStream class it will create a file before opening it for future writing. But the attempt to open the read-only file will thrown an exception.

Related

Is using the File class in Java how you create a file?

I need some serious help with concepts. I have been given background context on the class, specifically this:
I just need to understand the purpose of this class? Can I create a text file (or any other type of file) with its constructors? Is this just for handling files, if so, what does that mean?
Any help whatsoever will be greatly appreciated!
Thank you
You could use the java.io.File to create a file on the file system:
File myFile = new File("myFile.txt");
myFile.createNewFile();
Note that invoking the constructor won't create the file on the file system. To create an empty file, the createNewFile() method has to be invoked.
The File simply represents a abstraction of the file location, not the file itself. It comes with operations on the file identified by the path: exists(), delete(), length(), etc.
What you probably want is to use the classes that allow you to write content to a file:
If you are to write text, you should use the Writer interface.
If you are to write binary content, you should use the OutputStream interface.
The classes FileWriter and FileOutputStream are, respectively, the ones that link the File and Writer/OutputStream concepts together. Those classes create the file on the file-system for you.
FileWriter myFileWriter = null;
File myFile = new File("myFile.txt");
try {
// file is created on the file-system here
myFileWriter = new FileWriter(myFile);
myFileWriter.write("hello");
} finally {
if (myFileWriter != null) {
myFileWriter.close();
}
}
You can create a file using the File.createNewFile method, or, if you are using Java 7 or newer, using the newer Files.createFile method.
The difference between the old File and the new Path classes is that the former mixed a reference to a path to a file on the filsystem and operations you can do on it, and the latter is just representing the path itself but allows you to query it and analyze its structure.

Download .class file and load it into JVM

How can I download .class file and and load it into jvm using class loader , I have write a simple code simulates downloading a .class file the I tried to load it into JVM
public class face {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
File f = new File("Task.class");
int count;
byte[] buffer = new byte[1024];
DataInputStream dis = new DataInputStream(new FileInputStream(f));
StringBuilder all = new StringBuilder();
while ((count = dis.read(buffer)) > 0) {
// System.out.write(buffer, 0, count);
all.append(buffer);
// System.out.flush();
}
File b = new File("Task.class");
FileOutputStream fos = new FileOutputStream(b);
DataOutputStream dos = new DataOutputStream(fos);
dos.write(all.toString().getBytes());
ClassLoader lod = face.class.getClassLoader();
lod.loadClass(b.getAbsolutePath());
}
}
Use Class.forName(<package_qualified_class_name>)
First, I would like to applogies for the long list of suggestion here, but you have managed to cram an impressive number of mistakes into a small piece of code.
I suggest don't do any of these things
don't use DataInputStream or DataOutputStream when it doesn't add anything. You don't use any method which requires it.
don't write binary data to a StringBuilder. A StringBuilder is for text.
don't copy an entire buffer if you only read part of it. i.e. you need to record the length actual read and copy only the amount used.
don't append a byte[] to a StringBuilder. It won't do what you expect.
don't use a String to store binary data.
don't convert a String to byte[] using the default encoding unless you know you have ASCII data (which you don't)
don't write to a file you just read. As this doesn't make sense. You should have tested this works without the file copy and you would have found this didn't work, before you attempted something more complicated.
you can't write to a file which you still have open in windows. I suggest you close() a file when you are finished with it.
don't attempt to load a class using the file name. You load it by package.class name.
I suggest you try a one liner to load a class first and show this works. The class should appear in your class path, and when you write to the file, you should write it to a directory appropriate for the package.
Instead of doing all this, you could add a http://yourserver/basepath to your class path and it will load the classes from a web service. i.e. you might be able to do this without writing any code at all.

Do I have to create a new instance of fileinputstream if the file is changed constantly?

I have a xml log that is modified constantly by another application; however my Java code runs concurrently and checks for a couple of strings. I am using a SAX Parser. Now my question is will I have to have a new instance of a FileInputStream every time I loop through the file? How about the parser?
So let's say:
while(notfound)
{
FileInputStream fis = new FileInputStream(new File("c:/tmp/123.xml"));
SaxParser.parse(fis, sampleHandler);
notFound = sampleHandler.checkIfFound();
}
Thanks :D
In the example you provided, you will need a new FileInputStream each time you want to start reading from the beginning of the file. Stream classes don't often allow for manual positioning/resetting of the 'location', as since the name ('Stream') implies, it's just a pipe with bits spewing out of it.
Since you're using the SaxParser.parse() class method to initiate the parsing, it doesn't seem as though you actually have a parser object to re-create. So you should be fine with just re-creating the FileInputStream.
But! It seems like current versions of the SaxParser class support passing in a File instance as the first parameter, so you can just repeatedly use:
while(notfound)
{
SaxParser.parse(new File("c:/tmp/123.xml"), sampleHandler);
notFound = sampleHandler.checkIfFound();
}
Avoiding the re-creation of the FileInputStream altogether, and allowing the parser to handle that.

why new FileWriter("abc.txt") creates a new file and new File("abc.txt") does not?

new File("abc.txt") does not create actual file while new FileWriter("abc.txt") creates a file on disk. While going through source code i found that new FileWriter("abc.txt") eventually creates an object of file like new File()
Constructor of Class java.io.File does not create file on disk. It is just a abstraction over the file path. The file is created when you write to the file.
When you are creating FileWriter it calls constructor of FileOutputStream that calls a sequence of security checks and then invokes:
if (append) {
openAppend(name);
} else {
open(name);
}
Invocation of open() creates file on disk.
EDIT:
Here is how open() is defined:
/**
* Opens a file, with the specified name, for writing.
* #param name name of file to be opened
*/
private native void open(String name) throws FileNotFoundException;
I think file.createNewFile() creates the new file in actual.. please see following code for detal...
File file = new File("D:\\tables\\test.sql");
// if file does not exists, then create it
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
File doesn't always need to represent an actual file, it can be something you plan on creating, are guessing at the existence of, or something you've deleted as well.
From the JavaDoc for java.io.File:
An abstract representation of file and directory pathnames.
and
Instances of this class may or may not denote an actual file-system object such as a file or a directory.
In order to have the file actually be created, one needs to call createNEwFile(), whic according to the JavaDoc:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.
The File object is simply a representation of a file's location (URL) in the system. You can call createNewFile() on a File object in order to write our a file assuming one with that name does not already exist in that location.
When FileWriter creates a new File object internally, this is not what causes the file to come into existence. That happens in other parts of the code. A File object is just a standard way to designate a file (or directory), whether or not it exists.
There are lots of reasons really, but:
File is used by many classes in java.io. FileReader, etc... FileWriter is a "convenience" class that uses File and it enables the programmer to be more productive. Some Classes just want a File object which points to a file location and then they operate on it as needed to support their processing. Other Classes might support a FileWriter because it will only be writing to a file and not reading. It also makes the API more strongly-typed.

Does creation of new File(filename) object associate a process file descriptor with the object?

Does the following statement:
new File(filename);
associate a process file descriptor with the File object? Tried to search the same but without any success.
Ideally, it should not statically associate the file descriptor with the File object. Whenever, function calls are executed a file descriptor should get associated with the File Object for the period of time when the function call gets executed.
Any help appreciated.
There's no file descriptor, because new File(filename) does not open the file. It's just a easily manipulable representation of a path name.
File descriptors refer to open files. The fact that the file is not opened is not explicitly documented, but it follows from the principle of least surprise and from the fact that no exceptions are listed corresponding to failure to open the file.
No, new File(...) only is an object representing the filename, without even checking that there exists a file (or directory) with this name and/or path.
No. You can see this by examining the source of the File class yourself, from jdk 1.6.0_22:
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
Since you can call the File constructor with a path that doesn't yet exist, and since File objects can represent non-existent Files, it wouldn't be possible to associate descriptors with it.

Categories