Java - How to Lock Files Using File Channel (Java I/O Part 1)
Source: https://academy.oracle.com/en/oa-assets/i/c82/c82-java-fund-logo.jpg
What Will I Learn?
In this tutorial, I will guide you how to lock files by using File Channel while other processes will be blocked from attempting to gain access to the same file until the current process releases the lock. But, before we go any further, we need to grasp the fundamentals of reading from or writing to the stream based on the Java™ platform. A stream can represent many different kinds of sources and targets, including files, devices, memory or others.
- Java™ I/O Stream
- Java™ File Channel
Requirements
- Any current JDK.
- IntelliJ IDEA
Difficulty
- Basic
Tutorial Contents
Byte Streams
The Byte stream is the lowest layer and the most primitive of Java I/O to perform any operation against a bytes of
8 bit
s. Next, all the types of streams that we will learn are built on byte stream, and the abstract class ofInputStream
andOutputStream
is the superclass of all classes representing an input/ouput stream of bytes. This is the complete hierarchy:
public
abstract
class
java.io.
InputStream
extends
java.lang.
Object
implements
java.io.
Closeable
AudioInputStream
ByteArrayInputStream
FileInputStream
FilterInputStream
InputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
Example
Read file:D:/Test.txt
, then print its content onConsole
stream.
import java.io.FileInputStream; import java.io.IOException;
public class Main { public static void main(String[] args) { FileInputStream in = null; String plain = ""; try { in = new FileInputStream("D:/Test.txt"); byte[] bytes = new byte[5]; int i, n = bytes.length; while(in.read(bytes) > 0) { plain += new String(bytes); for(i = -1; ++i < n; bytes[i] = 0); } } catch(IOException e1) { if(in != null) try { in.close(); } catch(IOException e2) { e2.printStackTrace(); } } System.out.println(plain); } }Always Close Streams!
It is very important to close all streams, optionally inside thefinally
block to guarantee that they will be closed even if an error occurs. That practice helps us avoid serious resource leaks.Input
Output
References
Java Official - https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html
Android Official - https://developer.android.com/reference/java/io/InputStream.html
public
abstract
class
java.io.
OutputStream
extends
java.lang.
Object
implements
java.io.
Closeable
,java.io.
Flushable
ByteArrayOutputStream
FileOutputStream
FilterOutputStream
ObjectOutputStream
OutputStream
PipedOutputStream
Example
Write file toD:/out/Test.txt
from local variable.
import java.io.FileOutputStream; import java.io.IOException;
public class Main { public static void main(String[] args) { String message = "Murez Nasution" + System.lineSeparator() + "Hello, world!"; /** * The try-with-resources Statement */ try(FileOutputStream out = new FileOutputStream("D:/out/Test.txt")) { out.write(message.getBytes()); } catch(IOException e) { e.printStackTrace(); } System.out.println("Successful"); } }The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements
java.lang.AutoCloseable
, which includes all objects which implementjava.io.Closeable
, can be used as a resource.Output
References
Java Official:
https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Android Official - https://developer.android.com/reference/java/io/OutputStream.html
Character Streams
The character stream uses and often as wrappers for the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes. All character stream classes are descended from abstract classes
Reader
andWriter
. And here's the hierarchy:
public
abstract
class
java.io.
Reader
extends
java.lang.
Object
implements
java.io.
Closeable
,java.lang.
Readable
BufferedReader
CharArrayReader
FilterReader
InputStreamReader
PipedReader
StringReader
References
Java Official:
https://docs.oracle.com/javase/8/docs/api/java/io/Reader.html
https://docs.oracle.com/javase/tutorial/essential/io/charstreams.html
Android Official - https://developer.android.com/reference/java/io/Reader.html
public
abstract
class
java.io.
Writer
extends
java.lang.
Object
implements
java.io.
Closeable
,java.io.
Flushable
,java.lang.
Appendable
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
PipedWriter
PrintWriter
StringWriter
References
Java Official - https://docs.oracle.com/javase/8/docs/api/java/io/Writer.html
Android Official - https://developer.android.com/reference/java/io/Writer.html
Example
Now, we'll try to scan what you type in Console stream, then save them to the array ofString
. But, when user enters thestop
word exactly, the current scan will stop immediately. Next, the all of lines that saved in the memory will print out to the file:D:/Test.txt
.
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader;
public class Main { public static void main(String[] args) { System.out.println("Enter lines:"); final int N = 5; String[] lines = new String[N]; /** * Scan lines from Console */ try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { for(int i = 0; i < N; i++) { if((lines[i] = reader.readLine()).equals("stop")) break; } } catch(IOException e) { e.printStackTrace(); } /** * Print all of lines */ try(BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Test.txt"))) { int i = 0; String line; if((line = lines[i]) != null) writer.write(line); while(++i < N) if((line = lines[i]) != null) writer.write(System.lineSeparator() + line); } catch(IOException e) { e.printStackTrace(); } } }Input
Output
File Channel
And finally the time has come for us to implement file locking using File Channel. And here's the source codes.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.util.List;
public class Main { public static void main(String[] args) { try(RandomAccessFile r = new RandomAccessFile("D:/Lock.txt", "rw"); FileChannel fc = r.getChannel()) { /** * Lock file */ FileLock lock = fc.tryLock(); System.out.println("Locking file was successful"); System.out.println("Enter lines (to stop, type: \"stop\"):"); String line; List lines = new java.util.ArrayList<>(); try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) { while(!(line = reader.readLine()).equals("stop")) lines.add(line); } int i = 0, n; ByteBuffer buffer; buffer = ByteBuffer.wrap(lines.get(i).getBytes()); fc.write(buffer); for(n = lines.size(); ++i < n; ) { buffer = ByteBuffer.wrap((System.lineSeparator() + lines.get(i)).getBytes()); fc.write(buffer); } /** * You do not have to declare this, * because we already use try-with-resources which will close `lock` automatically. */ //lock.release(); } catch(IOException e) { e.printStackTrace(); } } }Testing
We'll try a simple test by creating a new file, i.e.:
D:/Lock.txt
and the whole contents come from the Console stream. The file will remain locked until the user has finished modifying the file.While we're typing and not trying to interrupt by giving the
stop
word, the file:D:/Lock.txt
will not be able to be changed by anyone. And you will get a message like in the picture below (running on Windows platform).Then when you release the lock (of course, by giving the input
stop
), then another process that is accessing the same file has been able to change the contents of the file.
Congratulations! We have successfully locked the file by using File Channel.
Thank you!
Share with heart
Posted on Utopian.io - Rewarding Open Source Contributors
I can learn a lot from your posts. Good job!
Thank you.
Keep following my posts.
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Hey @murez-nst I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x