Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Utility Class Fills in Java's Missing Functionality : Page 2

Anybody who regularly switches between Perl and Java can find Java lacking in elementary operations. Try out a utility that bundles all the methods and helper classes that Java is missing into one class.


advertisement
Missing or Broken Functionality
Since 1997, users have been trying to convince Sun to do something about chdir(); many believe that global change of a current directory in an application is a dangerous operation. For example, beans in an app server may inadvertently change global settings and destroy the functionality that other beans use. Other languages and other types of applications allow the behavior, and operating systems readily provide this functionality.

A naïve solution would be to set the system property, user.dir, which is used occasionally to resolve relative path problems. Unfortunately, public opinion about whether this solution is effective or not is split. As a result, Java still has a weird behavior. For instance, consider the following piece of code:

// create a temp directory new File("C:\\tmp\\tmpdir").mkdirs(); // try to chdir to c:\tmp System.setProperty("user.dir", "C:\\tmp"); // subdirectory, relative path File subdir = new File("tmpdir"); // check that its absolute path is what we want assertEquals("C:\\tmp\\tmpdir",subdir.getAbsolutePath()); // check that it is our new directory assertTrue(subdir.getAbsoluteFile().isDirectory()); // see that we were grossly misled assertFalse(subdir.isDirectory());



Here, the code resolves the file's relative path to absolute path in different ways in its java.io and native methods.

Another example, File.setLastModified(), a seemingly elementary operation, does not always work. I had to add a static setLastModified(File file) to the library to bypass this bug. It does the trick recommended in the aforementioned bug report (do System.gc() if the operation did not work during the first attempt).

Two other methods, chmod and chown, will probably never be implemented, since they are perceived as platform-dependent. I believe that the Java community could at least tolerate POSIX as a platform. The chmod method is represented in File.setReadOnly() (with no "Back" button); chown is just missing.

Convenient Read/Write
Often, all a Java developer needs to do with a file is read its entire contents as a byte array, a char array, or a string, or write an array or a string to a file (version: append to the end of the file). The following is a whole bunch of useful methods included in the Files utility class:

  • readBytesFromFile(String filename) (This one uses memory-mapped files introduced with java.nio.)
  • readBytesFromStream(InputStream is)
  • readStringFromFile(File file)
  • readStringFromFile(File file, String encoding)
  • readStringFromFile(String filename)
  • WriteBytesToFile, a.k.a. writeToFile(byte[]data, String fileTo)
  • writeToFile(char[]data, String fileTo)
  • writeToFile(CharSequence data, String fileTo)
  • writeToFile(InputStream is, String fileTo) (This one pipes bytes from an input stream to a file.)
  • appendBytesToFile(byte[]data, String fileTo) a.k.a. appendToFile, appendBytesToFile(char[]data, String fileTo) (This one takes lower bytes from char[] data.)
  • appendToFile(char[]data, String fileTo)
  • appendToFile(CharSequence data, String fileTo)

Memory-mapped File Copy
Java.nio offers an interesting method for copying files. Instead of reading each byte and writing it to another file, you can memory map the files. The whole copy operation may look like this:

FileInputStream is = new FileInputStream(from); FileOutputStream os = makeFile(to); os.getChannel().transferFrom(is.getChannel(), 0, from.length()); is.close(); os.close();

I tried to check whether one gains any advantage besides saving memory from using this, but benchmarking file copy is not easy. On a machine with 1GB of memory, I created eight 100MB files. I then copied them, one after another, to ensure that there was no trace of the first file in any cache. I timed only the first of these files and repeated the operation ten times, both with memory mapping and without. I spent two hours running it all and produced the following results:

  • It took 16.897558069 seconds to copy with NIO.
  • It took 17.638485729 seconds to copy without NIO.
  • NIO is 740.92766 milliseconds faster.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap