Skip to main content

Java Programming Hiccup! – Binary File Handling

I discovered something interesting in Java Programming. You may have come across output streams such as FileOutputStream, BufferedOutputStream and ObjectOutputStream when learning about binary file handling in Java. All of them have a particular method called flush(). The descriptions provided for this method for the last two output streams are as follows:

BufferedOutputStream: Flushes this buffered output stream. This forces any buffered output bytes to be written out to the underlying output stream.

ObjectOutputStream: Flushes the stream. This will write any buffered output bytes and flush through to the underlying stream.

As for FileOutputStream, the method is inherited from OutputStream, which gives this description:

Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.

The flush method of OutputStream does nothing.

My university’s lecture note gives this description for the flush method:

Flushes the output stream to force any buffered output bytes to be written to the file.

My understanding from all these, is that using the flush() method anywhere in the code would actually commit all the write actions (such as writeChar, writeUTF, etc) into the file stored in the hard disk.

Normally, all the write actions are stored in memory, and when the code calls the close() method, they are committed to the actual file in hard disk before closing this file. The flush() method promises to provide you a way to commit the write actions into the file without closing it.

This is useful when it is required for a program to (for example) accept a database record from the user and immediately store it into a file, instead of waiting for the user to finish entering all the records. I wanted to see this in action, so I went to test it out. Here is a snippet of the code:

  FileOutputStream fos = new FileOutputStream("database.dat");
  BufferedOutputStream bos = new BufferedOutputStream(fos);
  ObjectOutputStream oos = new ObjectOutputStream(bos);
  while (true) //infinite loop... see comment below
  {
    //code to accept and write database record
    //also includes condition to terminate while loop
    oos.flush(); //writes this record into file
  }
  oos.close(); //closes the file

I ran the code and watched the file changes using… no, nothing sophisticated, just Notepad2. Yea, you can set Notepad2 to appear “Always on Top” and set the “File Change Notification” to auto-reload, and you pretty much have a Watch window for the binary file. Make sure you have the binary file open in your Notepad2 though.

Disappointingly, it did not work. Every time the code encountered the flush() method, nothing happened. Seems like the underlined phrase above (“does nothing”) is correct! Well, I searched the Internet, and not many people have an answer to this problem. Some even happily use the flush method, thinking that it is committing all the write actions onto the file, not realizing their mistake.

But I stumbled upon a particular site: The Java Developers Almanac 1.4: e27. Forcing Updates to a File to the Disk. There are two interesting things here: The FileDescriptor and its sync() method. The descriptions given are:

XOutputStream.flush() method: Flush the data from the streams and writers into system buffers. The data may or may not be written to disk.

FileDescriptor.sync() method: Block until the system buffers have been written to disk. After this method returns, the data is guaranteed to have been written to disk.

Anyway I decided to try them out in my code. Here’s the snippet of my modified code. Notice the two new additions.

  FileOutputStream fos = new FileOutputStream("database.dat");
  BufferedOutputStream bos = new BufferedOutputStream(fos);
  ObjectOutputStream oos = new ObjectOutputStream(bos);
  FileDescriptor fd = fos.getFD(); //FileOutputStream only!
  while (true) //infinite loop... see comment below
  {
    //code to accept and write database record
    //also includes condition to terminate while loop
    oos.flush(); fd.sync(); //writes this record into file
  }
  oos.close(); //closes the file

I tested it out, and it works! The program now commits the record into the file in hard disk before accepting the next record. Just as I want it to.

Comments

Popular posts from this blog

Disable auto save in JetBrains IDE software (IntelliJ IDEA, PyCharm, PhpStorm)

JetBrains provides the following IDE software: IntelliJ IDEA PhpStorm PyCharm RubyMine WebStorm AppCode CLion Google also provides Android Studio which is powered by the IntelliJ platform. If you come from a different IDE such as Eclipse, you will be unpleasantly surprised to find that JetBrains-branded IDEs automatically save everything the moment you look away. The proponents argue that as you work on your project, you should not have to worry about saving files. But to others, this auto-save behavior which is enabled by default is a curse that catches them by surprise, and a shocking departure from the workflow they are very much used to. You can change the behavior by altering some settings.

Make Samsung DVD-C350 region-free

Update 2: An anonymous commentator has shown me a way to make Region 1 players (such as DVD-H1080R) region-free by first converting it to Region 3, then applying my region-free hack below. For details, click here or look for a comment by an Anonymous user dated 18 April 2011. Update: The instructions in the original post below did not make the DVD player region-free. Instead it only locked it to region 1. Many thanks to Anonymous who posted the first comment on this post, I now have alternate instructions. Note: If you have edited the numbers menu (see original post) , I suggest you return it to the original settings you had backed up. A modified numbers menu may prevent the instructions below from working properly.

Group, Ungroup and Regroup disabled in Word

I was editing a Microsoft Word document which had a collection of shapes and text boxes grouped together. I wanted to modify some of the shapes, and therefore I had to ungroup them. But when I right-click the group and open the Group menu, all three options namely Group, Ungroup and Regroup are completely disabled or grayed out. I couldn’t figure out what’s wrong. This group of objects is perfectly ungroupable, and I can even select objects within the group. However, Microsoft Word 2007 is not letting me ungroup it. I searched the Internet for a solution, but did not find anything very useful. The closest I came across is this statement: “The type of Text Wrapping doesn't make any difference as long as it isn't In Line with Text.” ( Link here ) Anyway, I changed the text wrapping of the group of objects from ‘In line with Text’ to ‘Tight’ and viola! I could now ungroup it and edit it. The document got a bit messed up when I did so, but after I ungrouped, edited and regro...