Java - How to Lock Files Using File Channel (Java I/O Part 1)

in #utopian-io7 years ago (edited)

c82-java-fund-logo.jpg
Source: https://academy.oracle.com/en/oa-assets/i/c82/c82-java-fund-logo.jpg

<h4>What Will I Learn? <p dir="auto">In this tutorial, I will guide you how to lock files by using <strong>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 <em>stream based on the Java™ platform. A <em>stream can represent many different kinds of sources and targets, including files, devices, memory or others. <ul> <li>Java™ I/O Stream <li>Java™ File Channel <hr /> <h4>Requirements <ul> <li>Any current <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">JDK. <li><a href="https://www.jetbrains.com/idea/download/" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">IntelliJ IDEA <hr /> <h4>Difficulty <ul> <li>Basic <hr /> <h4>Tutorial Contents <ul> <li><h5>Byte Streams <p dir="auto">The Byte stream is the lowest layer and the most primitive of Java I/O to perform any operation against a bytes of <code>8 bits. Next, all the types of streams that we will learn are built on byte stream, and the abstract class of <code>InputStream and <code>OutputStream is the superclass of all classes representing an input/ouput stream of bytes. This is the complete hierarchy:<br /> <sup><code>public <sup><code>abstract <sup><code>class <code>java.io.<strong><code>InputStream<br /> <sup><code>extends <code>java.lang.<strong><code>Object<br /> <sup><code>implements <code>java.io.<strong><code>Closeable <ul> <li><a href="https://docs.oracle.com/javase/8/docs/api/javax/sound/sampled/AudioInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>AudioInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>ByteArrayInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FileInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FilterInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FilterInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/org/omg/CORBA/portable/InputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>InputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>ObjectInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/PipedInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>PipedInputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/SequenceInputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>SequenceInputStream<br /> <sub><strong>Example<br /> Read file: <code>D:/Test.txt, then print its content on <code>Console stream. <pre><code> import java.io.FileInputStream; import java.io.IOException; <br /> 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); } } <blockquote> <p dir="auto"><strong>Always Close Streams!<br /> It is very important to close all streams, optionally inside the <code>finally block to guarantee that they will be closed even if an error occurs. That practice helps us avoid serious resource leaks. <p dir="auto"><sub><strong>Input<br /> <img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077739/feialkseeyqrgulruirq.png" alt="Untitled 007.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077739/feialkseeyqrgulruirq.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077739/feialkseeyqrgulruirq.png 2x" /> <p dir="auto"><sub><strong>Output<br /> <img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077847/svfrdqdoby51nanyj4hr.png" alt="Untitled 008.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077847/svfrdqdoby51nanyj4hr.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516077847/svfrdqdoby51nanyj4hr.png 2x" /> <p dir="auto"><sub><strong>References<br /> <strong>Java Official - <a href="https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html<br /> <strong>Android Official - <a href="https://developer.android.com/reference/java/io/InputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://developer.android.com/reference/java/io/InputStream.html <hr /> <p dir="auto"><br /><br /> <sup><code>public <sup><code>abstract <sup><code>class <code>java.io.<strong><code>OutputStream<br /> <sup><code>extends <code>java.lang.<strong><code>Object<br /> <sup><code>implements <code>java.io.<strong><code>Closeable, <code>java.io.<strong><code>Flushable <ul> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayOutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>ByteArrayOutputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FileOutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FileOutputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FilterOutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FilterOutputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>ObjectOutputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/org/omg/CORBA/portable/OutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>OutputStream <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/PipedOutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>PipedOutputStream<br /> <sub><strong>Example<br /> Write file to <code>D:/out/Test.txt from local variable. <pre><code> import java.io.FileOutputStream; import java.io.IOException; <br /> 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"); } } <blockquote> <p dir="auto">The <em>try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements <code>java.lang.AutoCloseable, which includes all objects which implement <code>java.io.Closeable, can be used as a resource. <p dir="auto"><sub><strong>Output<br /> <img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516086066/qfsc2ovsh7incxm3cvmh.png" alt="Untitled 009.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516086066/qfsc2ovsh7incxm3cvmh.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516086066/qfsc2ovsh7incxm3cvmh.png 2x" /> <p dir="auto"><sub><strong>References<br /> <strong>Java Official:<br /> <a href="https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html<br /> <a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html<br /> <strong>Android Official - <a href="https://developer.android.com/reference/java/io/OutputStream.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://developer.android.com/reference/java/io/OutputStream.html <hr /> <ul> <li><h5>Character Streams <p dir="auto">The character stream uses and often as <em>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 <code>Reader and <code>Writer. And here's the hierarchy:<br /> <sup><code>public <sup><code>abstract <sup><code>class <code>java.io.<strong><code>Reader<br /> <sup><code>extends <code>java.lang.<strong><code>Object<br /> <sup><code>implements <code>java.io.<strong><code>Closeable, <code>java.lang.<strong><code>Readable <ul> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>BufferedReader <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/CharArrayReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>CharArrayReader <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FilterReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FilterReader <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/InputStreamReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>InputStreamReader <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/PipedReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>PipedReader <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/StringReader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>StringReader<br /> <sub><strong>References<br /> <strong>Java Official:<br /> <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Reader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/8/docs/api/java/io/Reader.html<br /> <a href="https://docs.oracle.com/javase/tutorial/essential/io/charstreams.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/tutorial/essential/io/charstreams.html<br /> <strong>Android Official - <a href="https://developer.android.com/reference/java/io/Reader.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://developer.android.com/reference/java/io/Reader.html <hr /> <p dir="auto"><br /><br /> <sup><code>public <sup><code>abstract <sup><code>class <code>java.io.<strong><code>Writer<br /> <sup><code>extends <code>java.lang.<strong><code>Object<br /> <sup><code>implements <code>java.io.<strong><code>Closeable, <code>java.io.<strong><code>Flushable, <code>java.lang.<strong><code>Appendable <ul> <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/BufferedWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>BufferedWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/CharArrayWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>CharArrayWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/FilterWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>FilterWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/OutputStreamWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>OutputStreamWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/PipedWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>PipedWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>PrintWriter <li><a href="https://docs.oracle.com/javase/8/docs/api/java/io/StringWriter.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link"><code>StringWriter<br /> <sub><strong>References<br /> <strong>Java Official - <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Writer.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://docs.oracle.com/javase/8/docs/api/java/io/Writer.html<br /> <strong>Android Official - <a href="https://developer.android.com/reference/java/io/Writer.html" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://developer.android.com/reference/java/io/Writer.html<br /> <sub><strong>Example<br /> Now, we'll try to scan what you type in Console stream, then save them to the array of <code>String. But, when user enters the <code>stop word exactly, the current scan will stop immediately. Next, the all of lines that saved in the memory will print out to the file: <code>D:/Test.txt. <pre><code> import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; <br /> 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(); } } } <p dir="auto"><sub>Input<br /> <img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093378/li19mhqor1faeleqpqyi.png" alt="Untitled 010.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093378/li19mhqor1faeleqpqyi.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093378/li19mhqor1faeleqpqyi.png 2x" /><br /> <sub>Output<br /> <img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093501/ledht3tm9rx4vzymsal5.png" alt="Untitled 011.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093501/ledht3tm9rx4vzymsal5.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516093501/ledht3tm9rx4vzymsal5.png 2x" /> <hr /> <ul> <li><h5>File Channel <p dir="auto">And finally the time has come for us to implement file locking using <em>File Channel. And here's the source codes. <pre><code> 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; <br /> 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(); } } } <h4>Testing <p dir="auto">We'll try a simple test by creating a new file, i.e.: <code>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. <p dir="auto"><img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516096907/lhlqqijr28jhgfpjpe1j.png" alt="Untitled 012.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516096907/lhlqqijr28jhgfpjpe1j.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516096907/lhlqqijr28jhgfpjpe1j.png 2x" /> <p dir="auto">While we're typing and not trying to interrupt by giving the <code>stop word, the file:<code>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). <p dir="auto"><img src="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516097190/suwtka50swkllqsrspgs.png" alt="Untitled 013.png" srcset="https://images.hive.blog/768x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516097190/suwtka50swkllqsrspgs.png 1x, https://images.hive.blog/1536x0/https://res.cloudinary.com/hpiynhbhq/image/upload/v1516097190/suwtka50swkllqsrspgs.png 2x" /> <p dir="auto">Then when you release the lock (of course, by giving the input <code>stop), then another process that is accessing the same file has been able to change the contents of the file.<br /> Congratulations! We have successfully locked the file by using File Channel. <hr /> <h4>Thank you! <p dir="auto">Share with heart <p dir="auto"><br /><hr /><em>Posted on <a href="https://utopian.io/utopian-io/@murez-nst/mureztutorial006" target="_blank" rel="noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">Utopian.io - Rewarding Open Source Contributors<hr /><p>
Sort:  

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

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • Seems like you contribute quite often. AMAZING!

Suggestions

  • Contribute more often to get higher and higher rewards. I wish to see you often!
  • Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck!

Get Noticed!

  • Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

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