|
Java Tutorial |
FilesThese pages make up the course notes for my Java programming course (run at Dallam, Milnthorpe, Cumbria). Hopefully they also make a useful self-learning tutorial. via a diversion around the command line A lot of programs need to load and store data. The way we do this on pretty much all modern computers is using Files (and folders or directories). In the previous section we looked at classes and objects and I mentioned that Files were a class from which we can create objects. Lets have a look at some things we can do with files. We will start off by creating a class that gives some details about files. It would be useful if we could use this class without having to edit it each time we want to show the details of a different file (think back to the Create a new class called You can create the package in the File->New->Class dialogue Now paste the following code
package tuorial.files;
import java.io.File;
import java.io.IOException;
public class FileDetails {
public void displayFileInfo(String filePath){
File file = new File(filePath);
try {
if (file.exists()) {
displayString("Details for file " + file.getName());
displayString("in folder " + file.getCanonicalPath());
displayString("\t Last Modified " + file.lastModified() );
displayString("\t Size (bytes) " + file.length());
}
else {
displayString("File not found");
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void displayString(String text) {
System.out.println(text);
}
public static void main(String[] args){
FileDetails fileDetails = new FileDetails();
fileDetails.displayFileInfo(args[0]);
}
}
Try running this (right click the You should get an error at tuorial.files.FileDetails?.main(FileDetails?.java:39) The message indicates that the error is on line 39 (in my code, yours may be different), looking at line 39 in my code: The error message says We have created lots of main methods and they always look like We now know that If you have ever run a command from the command line (DOS prompt, shell prompt, etc.) you have most probably used command line arguments, e.g. something like Now you may be thinking that this is not very useful, however it is a very common technique. Arguments can be passed to programs in short cuts and in batch/script files as well as on the command line. Sometimes it is not very convenient to have to type something in every time a program runs (especially if it is a long piece of text, such as the path to a file or directory) and it is better to have it stored in a short-cut or batch file. Software developers tend to use the command line quite a lot - it is a powerful tool that you should get to know. But... we are not running this from the command line, we are running it from within the IDE, so how do we tell the IDE what we want to pass to the program? Right click the In the arguments box enter the name of a file - remember to include the full path. I have choosen to use the If you want you can also try running from the command line Try looking at the Specification for the File class http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html and add some more file details to the output (e.g. canWrite, isFile). Try using the input pop-up to get the file name rather than using the command line Try making it work with either the command line or the input pop-up (hint - if there is no command line argument then display the pop-up) Reading and Writing Files It's all very well getting details of a file, but things get a bit more useful when we can read data from, and write data to files. Before we get into the nitty-gritty we need to have a bit of an understanding of what may be in a file. At a basic level there are two types of file, Text (also called ASCII) and Binary. A Text file contains character data represented by a standard encoding system (for example American Standard Code for information Interchange - ASCII, or may be another encoding system like Unicode). These are the sort of files we create to hold our source code, or that you create with Notepad or other text editors. A Binary file contains data that may be in any form, but which is not necessarily decodable into Character Strings. Executable files, files created by most "Office" applications, PDFs?, etc, are all binary files. Try opening a word-processor file with a text editor (such as Notepad), you may well see that there are a lot of strange characters in there. You may also spot some readable text. Normally it is easier to develop programs that read and write Text files, and that is what we are going to do from here on. Reading files So lets state clearly what we want to do and then think about how we want to do it. We want to:
Is that everything we need to achieve? see if you can think of any other things we may need to consider For now let's write something that meets the requirements listed above. It may be better to start of with a more detailed set of requirements but, this is a learning process. It is also often good to start simply and build up, even if this means rewriting some code. In anything but the most trivial system, you are unlikely to be able think of all the nuances before writing a line of code. As you get more experience, you will be able to state the requirements for a program more comprehensivly. Create another class and paste in the following to get started Remeber to use the correct package and class
package tuorial.files;
import java.io.*;
public class ContextSearch {
/**
* run through all files in a directory
*
* @param path - the path to the directory to process
*/
public void processDirectory(String path, String text) {
File dir = new File(path);
for (String fileName : dir.list()) {
searchFile(fileName, text);
}
}
/**
* search a for a text string
*
* @param file - the file to read
* @param text - the text to find
*/
public void searchFile(String file, String text) {
try {
BufferedReader in = new BufferedReader(new FileReader(file));
String line;
while ((line = in.readLine()) != null) {
if (line.indexOf(text) > -1) {
System.out.println("Found: " + line + " in " + file);
}
}
in.close();
} catch (IOException e) {
//let everyone know there was a problem
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
ContextSearch cs = new ContextSearch();
cs.processDirectory(args[0], args[1]);
}
}
Try running it on some files - I suggest you use the source code you have created for this tutorial. Remember to set up the command line arguments as described above. I used the path to my "tutorial" source folder and "Vat" as the command line arguments as shown below (there is a space between D:\_work\java\tutorial\ and Vat ![]() On running it I got the following error and output - your may be different. ![]() What do you think has gone wrong? First lets consider the error, on looking at the contents of the directory being searched I notice that it has a sub-directory which is also called "tutorial". The error says Access Denied but I suspect that that message is a bit misleading, I'm guessing that we tried to open a directory as a file and the Operating System prevented us from doing that - hence the Access Denied. Also there are a lot of odd characters in the output. Notice that these are associated with .class files. When we compile a java program (something that Eclipse automatically does for us) the source code, in a file with a .java extension is compiled into a file with a .class extension. These files contain binary data, and as discussed above, this data is not generally readable as character strings. Think about how to fix these problems
Writing The final thing we need to know about files is how to write data to them. This is basically the only way your application can store data permanently. So if you want to keep some information so that it can be accessed later (after the program has been closed, the system shut down, etc), you need to write it to a file. The process is structurally similar to reading a file, i.e. Open the file, write to it, and close it. We can open a file for writing or appending, writing always creates a new file (and overwrites any existing file of the same name) appending adds to the end of the file. In the example above, we created a useful little utility program that finds text in a file and prints it out with some context. Let's have a go at creating another little utility. I often find myself working on many different computers, in different places, on different networks. What would be nice is to have all my favourite webpage links stored on a USB Memory Stick so that I can take them around with me. (I know there are on-line book mark services, but you have to log in, and remember the url of the on-line service, etc.) It turns out that a web-page is just an ASCII file with some special "Mark Up" in it. So if I save my book marks to a file in the correct format it will open in the Web Browser and I will have a page of links. I can then just click a link and go to that site. What is needed is an easy way of adding links to the file. To illustrate this, copy the HTML below and paste it into a file called bookmarks.hmtl (You can use Eclipse to do this, or a text editor like notepad).
<html>
<head>
<title>My Bookmarks</title>
</head>
<body>
<a href="http://www.google.co.uk">Google</a>
<a href="http://www.bbc.co.uk">BBC</a>
<body>
</html>
Now find the file - where ever you saved it - in the file system Explorer (e.g. windows explorer) and double click it, because we saved it with an extension of .html it should open with your web browser and you should be able to click the links and go to the sites. That's ok, but it is a bit cumbersome to have to type all the To split the task up a little, there are two things we need to do:
If you have been working through this tutorial you will remember that we used a pop-up input box in the To make things simple make sure you have a copy of the Now create a new class called Bookmarks, again set the package to tutorial.files. Here's how I began to code the Bookmarks class:
package tuorial.files;
public class Bookmarks {
public String url;
public String title;
public String file;
/**
* constructor, set up a default file name if none supplied
*
* @param file - the name of the bookmark file or null to default
*/
public Bookmarks(String file) {
if (file == null) {
this.file = "Bookmarks.html";
}
else {
this.file = file;
}
}
/**
* add a bookmark to the file
*
*/
public void addBookMark() {
}
/**
* prompt the user for input
*
*/
public void promptUser() {
this.url = InputPopUp.prompt("Enter the URL");
this.title = InputPopUp.prompt("Enter the Title (or leave blank)");
}
public static void main(String[] args) {
String fileArg=null;
if (args.length > 0) fileArg=args[0];
Bookmarks bookmarks = new Bookmarks(fileArg);
bookmarks.promptUser();
bookmarks.addBookMark();
}
}
Most of the code above deals with creating a bookmarks object from the Bookmarks class, and assiging a name for the So what we need to do now is fill in the Firstly we need to open the file for apending. There are a confusing number of classes in the java.io package for reading and writing files. We are going to use the So here is the initial code that opens the file for append and catches any exceptions should it fail to open.
try {
//open the file for appending
BufferedWriter out = new BufferedWriter(new FileWriter(this.file, true));
} catch (IOException e) {
e.printStackTrace();
}
Having opened the file we need to write something to it. Stop and think about what we need to write and have a go at writing some code to do this. Things to think about are:
Having done that we need to close the file which we do with: If we don't close the file, then the things we tried to write may not actually be saved. Here is what my completed method looked like:
try {
//open the file for appending
BufferedWriter out = new BufferedWriter(new FileWriter(this.file, true));
//if the title is blank (null) use the url as the title
String myTitle = this.title;
if (this.title == null ) myTitle = this.url;
String link = "<a href='" + this.url + "'>" + myTitle + "</a><br>";
out.write(link);
//append a new line character
out.newLine();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
This work is Copyright Chris Hunter 2007, you may use it for non-commercial purposes |