import java.io.*;

public class CopyFile{

private static void copyfile(String srFile, String dtFile){

try{

File f1 = new File(srFile);

File f2 = new File(dtFile);

InputStream in = new FileInputStream(f1);

//For Append the file.

//OutputStream out = new FileOutputStream(f2,true);

//For Overwrite the file.

OutputStream out = new FileOutputStream(f2);

byte[] buf = new byte[1024];

int len;

while ((len = in.read(buf)) > 0){

out.write(buf, 0, len);

}

in.close();

out.close();

System.out.println("File copied.");

}

catch(FileNotFoundException ex){

System.out.println(ex.getMessage() + " in the specified directory.");

System.exit(0);

}

catch(IOException e){

System.out.println(e.getMessage());

}

}

public static void main(String[] args){

switch(args.length){

case 0: System.out.println("File has not mentioned.");

System.exit(0);

case 1: System.out.println("Destination file has not mentioned.");

System.exit(0);

case 2: copyfile(args[0],args[1]);

System.exit(0);

default : System.out.println("Multiple files are not allow.");

System.exit(0);

}

}

}

Although most of the classes defined byjava.iooperate on streams, theFileclass does not. It deals directly with files and the file system. That is, theFileclass does not specify how information is retrieved from or stored in files; it describes the properties of a file itself. AFileobject is used to obtain or manipulate the information associated with a disk file, such as the permissions, time, date, and directory path, and to navigate subdirectory hierarchies.

Files are a primary source and destination for data within many programs. Although there are severe restrictions on their use within applets for security reasons, files are still a central resource for storing persistent and shared information. A directory in Java is treated simply as aFilewith one additional property-a list of filenames that can be examined by thelist()method.

The following constructors can be used to createFileobjects:

File(StringdirectoryPath)
File(StringdirectoryPath,Stringfilename)
File(FiledirObj, Stringfilename)

Here,directoryPathis the path name of the file,filenameis the name of the file, anddirObjis aFileobject that specifies a directory.

The following example creates three files:f1,f2, andf3. The firstFileobject is constructed with a directory path as the only argument. The second includes two arguments-the path and the filename. The third includes the file path assigned tof1and a filename;f3refers to the same file asf2.

File f1 = new File("/");
File f2 = new File("/","autoexec.bat");
File f3 = new File(f1,"autoexec.bat");

Note:Java does the right thing with path separators between UNIX and Windows/DOS conventions. If you use a forward slash (/) on a Windows version of Java, the path will still resolve correctly. Remember, if you are using the Windows/DOS convention of a backslash character (\\), you will need to use its escape sequence (\\\\) within a string. The Java convention is to use the UNIX- and URL-style forward slash for path separators.

Filedefines many methods that obtain the standard properties of aFileobject. For example,getName()returns the name of the file,getParent()returns the name of the parent directory, andexists( )returnstrueif the file exists,falseif it does not. TheFileclass, however, is not symmetrical. By this, we mean that there are many methods that allow you toexaminethe properties of a simple file object, but no corresponding function exists to change those attributes. The following example demonstrates several of theFilemethods:

// Demonstrate File.
import java.io.File;
class FileDemo {
static void p(String s) {
System.out.println(s);
}
public static void main(String args[]) {
File f1 = new File("/java/COPYRIGHT");
p("File Name: " + f1.getName());
p("Path: " + f1.getPath());
p("Abs Path: " + f1.getAbsolutePath());
p("Parent: " + f1.getParent());
p(f1.exists() ? "exists" : "does not exist");
p(f1.canWrite() ? "is writeable" : "is not writeable");
p(f1.canRead() ? "is readable" : "is not readable");
p("is " + (f1.isDirectory() ? "" : "not" + " a directory"));
p(f1.isFile() ? "is normal file" : "might be a named pipe");
p(f1.isAbsolute() ? "is absolute" : "is not absolute");
p("File last modified: " + f1.lastModified());
p("File size: " + f1.length() + " Bytes");
}
}

When you run this program, you will see something similar to the following:

File Name: COPYRIGHT
Path: /java/COPYRIGHT
Abs Path: /java/COPYRIGHT
Parent: /java
exists
is writeable
is readable
is not a directory
is normal file
is absolute
File last modified: 812465204000
File size: 695 Bytes

Most of theFilemethods are self-explanatory.isFile()andisAbsolute()are not.isFile()returnstrueif called on a file andfalseif called on a directory. Also,isFile()returnsfalsefor some special files, such as device drivers and named pipes, so this method can be used to make sure the file will behave as a file. TheisAbsolute()method returnstrueif the file has an absolute path andfalseif its path is relative.

Filealso includes two useful utility methods. The first isrenameTo(), shown here:

boolean renameTo(File newName)

Here, the filename specified bynewNamebecomes the new name of the invokingFileobject. It will returntrueupon success andfalseif the file cannot be renamed (if you either attempt to rename a file so that it moves from one directory to another or use an existing filename, for example).

The second utility method isdelete(), which deletes the disk file represented by the path of the invokingFileobject. It is shown here:

boolean delete( )

You can also usedelete()to delete a directory if the directory is empty.delete()returnstrueif it deletes the file andfalseif the file cannot be removed.

Java File class represents the files and directory pathnames in an abstract manner. This class is used for creation of files and directories, file searching, file deletion etc.

The File object represents the actual file/directory on the disk. There are following constructors to create a File object:

Following syntax creates a new File instance from a parent abstract pathname and a child pathname string.

File(File parent,String child);

Following syntax creates a new File instance by converting the given pathname string into an abstract pathname.

File(String pathname)

Following syntax creates a new File instance from a parent pathname string and a child pathname string.

File(String parent,String child)

Following syntax creates a new File instance by converting the given file: URI into an abstract pathname.

File(URI uri)

Once you haveFileobject in hand then there is a list of helper methods which can be used manipulate the files.

SN / Methods with Description
1 / public String getName()
Returns the name of the file or directory denoted by this abstract pathname.
2 / public String getParent()
Returns the pathname string of this abstract pathname's parent, or null if this pathname does not name a parent directory.
3 / public File getParentFile()
Returns the abstract pathname of this abstract pathname's parent, or null if this pathname does not name a parent directory.
4 / public String getPath()
Converts this abstract pathname into a pathname string.
5 / public boolean isAbsolute()
Tests whether this abstract pathname is absolute. Returns true if this abstract pathname is absolute, false otherwise
6 / public String getAbsolutePath()
Returns the absolute pathname string of this abstract pathname.
7 / public boolean canRead()
Tests whether the application can read the file denoted by this abstract pathname. Returns true if and only if the file specified by this abstract pathname exists and can be read by the application; false otherwise.
8 / public boolean canWrite()
Tests whether the application can modify to the file denoted by this abstract pathname. Returns true if and only if the file system actually contains a file denoted by this abstract pathname and the application is allowed to write to the file; false otherwise.
9 / public boolean exists()
Tests whether the file or directory denoted by this abstract pathname exists. Returns true if and only if the file or directory denoted by this abstract pathname exists; false otherwise
10 / public boolean isDirectory()
Tests whether the file denoted by this abstract pathname is a directory. Returns true if and only if the file denoted by this abstract pathname exists and is a directory; false otherwise.
11 / public boolean isFile()
Tests whether the file denoted by this abstract pathname is a normal file. A file is normal if it is not a directory and, in addition, satisfies other system-dependent criteria. Any non-directory file created by a Java application is guaranteed to be a normal file. Returns true if and only if the file denoted by this abstract pathname exists and is a normal file; false otherwise.
12 / public long lastModified()
Returns the time that the file denoted by this abstract pathname was last modified. Returns a long value representing the time the file was last modified, measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970), or 0L if the file does not exist or if an I/O error occurs.
13 / public long length()
Returns the length of the file denoted by this abstract pathname. The return value is unspecified if this pathname denotes a directory.
14 / public boolean createNewFile() throws IOException
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. Returns true if the named file does not exist and was successfully created; false if the named file already exists.
15 / public boolean delete()
Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted. Returns true if and only if the file or directory is successfully deleted; false otherwise.
16 / public void deleteOnExit()
Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
17 / public String[] list()
Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname.
18 / public String[] list(FilenameFilter filter)
Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.
20 / public File[] listFiles()
Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.
21 / public File[] listFiles(FileFilter filter)
Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.
22 / public boolean mkdir()
Creates the directory named by this abstract pathname. Returns true if and only if the directory was created; false otherwise.
23 / public boolean mkdirs()
Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Returns true if and only if the directory was created, along with all necessary parent directories; false otherwise.
24 / public boolean renameTo(File dest)
Renames the file denoted by this abstract pathname. Returns true if and only if the renaming succeeded; false otherwise.
25 / public boolean setLastModified(long time)
Sets the last-modified time of the file or directory named by this abstract pathname. Returns true if and only if the operation succeeded; false otherwise.
26 / public boolean setReadOnly()
Marks the file or directory named by this abstract pathname so that only read operations are allowed. Returns true if and only if the operation succeeded; false otherwise.
27 / public static File createTempFile(String prefix, String suffix, File directory) throws IOException
Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name. Returns an abstract pathname denoting a newly-created empty file.
28 / public static File createTempFile(String prefix, String suffix) throws IOException
Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name. Invoking this method is equivalent to invoking createTempFile(prefix, suffix, null). Returns abstract pathname denoting a newly-created empty file.
29 / public int compareTo(File pathname)
Compares two abstract pathnames lexicographically. Returns zero if the argument is equal to this abstract pathname, a value less than zero if this abstract pathname is lexicographically less than the argument, or a value greater than zero if this abstract pathname is lexicographically greater than the argument.
30 / public int compareTo(Object o)
Compares this abstract pathname to another object. Returns zero if the argument is equal to this abstract pathname, a value less than zero if this abstract pathname is lexicographically less than the argument, or a value greater than zero if this abstract pathname is lexicographically greater than the argument.
31 / public boolean equals(Object obj)
Tests this abstract pathname for equality with the given object. Returns true if and only if the argument is not null and is an abstract pathname that denotes the same file or directory as this abstract pathname.
32 / public String toString()
Returns the pathname string of this abstract pathname. This is just the string returned by the getPath() method.

Example:

Following is the example to demonstrate File object:

import java.io.File;

publicclassDirList{

publicstaticvoid main(String args[]){

String dirname ="/tmp";

File f1 =newFile(dirname);

if(f1.isDirectory()){

System.out.println("Directory of "+ dirname);

String s[]= f1.list();

for(int i=0; i s.length; i++){

File f =newFile(dirname +"/"+ s[i]);

if(f.isDirectory()){

System.out.println(s[i]+" is a directory");

}else{

System.out.println(s[i]+" is a file");

}

}

}else{

System.out.println(dirname +" is not a directory");

}

}

}

This would produce the following result:

Directory of /mysql

bin is a directory

lib is a directory

demo is a directory

test.txt is a file

README is a file

index.html is a file

include is a directory

Java Concurrency – Part 3 : Synchronization with intrinsic locks

After learning how tocreate threadsandmanipulate them, it’s time to go to most important things : synchronization.

Synchronization is a way to make some code thread safe. A code that can be accessed by multiple threads must be made thread safe. Thread Safe describe some code that can be called from multiple threads without corrupting the state of the object or simply doing the thing the code must do in right order.

For example, we can take this little class :

1 / publicclassExample {
2 / privateintvalue = 0;
3
4 / publicintgetNextValue(){
5 / returnvalue++;
6 / }
7 / }

It’s really simple and works well with one thread, but absolutely not with multiple threads. An increment like this is not a simple action, but three actions :

  • Read the current value of “value”
  • Add one to the current value
  • Write that new value to “value”

Normally, if you have two threads invoking the getNextValue(), you can think that the first will get 1 and the next will get 2, but it is possible that the two threads get the value 1. Imagine this situation :

Thread 1 : read the value, get 0, add 1, so value = 1
Thread 2 : read the value, get 0, add 1, so value = 1
Thread 1 : write 1 to the field value and return 1
Thread 2 : write 1 to the field value and return 1

These situations come from what we call interleaving. Interleaving describe the possible situations of several threads executing some statements. Only for three operations and two threads, there is a lot of possible interleavings.

So we must made the operations atomic to works with multiple threads. In Java, the first way to make that is to use a lock. All Java objects contains an intrinsic locks, we’ll use that lock to make methods or statement atomic. When a thread has a lock, no other thread can acquire it and must wait for the first thread to release the lock. To acquire the lock, you have to use the synchronized keyword to automatically acquire and release a lock for a code. You can add the synchronized keyword to a method to acquire the lock before invoking the method and release it after the method execution. You can refactor the getNextValue() method using the synchronized keyword :

1 / publicclassExample {
2 / privateintvalue = 0;
3
4 / publicsynchronizedintgetNextValue(){
5 / returnvalue++;
6 / }
7 / }

With that, you have the guarantee that only thread can execute the method at the same time. The used lock is the intrinsic lock of the instance. If the method is static, the used lock is the Class object of Example. If you have two methods with the synchronized keyword, only one method of the two will be executed at the same time because the same lock is used for the two methods. You can also write it using a synchronized block :

1 / publicclassExample {
2 / privateintvalue = 0;
3
4 / publicintgetNextValue() {
5 / synchronized(this) {
6 / returnvalue++;
7 / }
8 / }
9 / }

This is exactly the same as using the synchronized keyword on the method signature. Using synchronized blocks, you can choose the lock to block on. By example, if you don’t want to use the intrinsic lock of the current object but an other object, you can use an other object just as a lock :

1 / publicclassExample {
2 / privateintvalue = 0;
3
4 / privatefinalObject lock = newObject();
5
6 / publicintgetNextValue() {
7 / synchronized(lock) {
8 / returnvalue++;
9 / }
10 / }
11 / }

The result is the same but has one difference, the lock is internal to the object so no other code can use the lock. With complex classes, it not rare to use several locks to provide thread safety on the class.

There is an other issue with multiple threads : the visibility of the variables. This seems when a change made by a thread is visible by an other thread. For performance improvements, the Java compiler and virtual machines can made some improvements using registers and cache. By default, you have no guarantee that a change made by a thread is visible to an other thread. To make a change visible to an other thread, you must use synchronized blocks to ensure visibility of the change. You must use synchronized blocks for the read and for the write of the shared values. You must make that for every read/write of a value shared between multiple threads.

You can also use the volatile keyword on the field to ensure the visibility of read/write between multiple threads. The volatile keyword ensure only visibility, not atomicity. The synchronized blocks ensure visibility and atomicity. So you can use the volatile keyword on fields that doesn’t need atomicity (if you make only read and write to the field without depending on the current value of the field by example).