So, by now you should know how to create and delete Files and Directories as described in the previous post – How To Do Basic Operations With Files In Java and you should know different parts of the Java File API.
What now? Well, if you are like me, you are going to want to know how to read and write from files too, since creating and deleting files on its own does not seem very helpful (unless you’re planning to code some virus that just creates and multiplies new files to mess up people’s hard drives :S)
First off to start this I want to present you with some very important concepts:
- Streams – Read/Write binary data one byte at a time
- Readers/Writers – Read/Write from and to text files one char at a time
- Buffered – Wrapper of any of the above, Read/Write many bytes/chars, useful in almost 99.9% of the cases
So to read/write a file we need to keep in mind we have to do 4 things:
- Get the File object, linked to the existing File (otherwise create it)
- Create an Input or Output Stream from or to the file (Using FileInputStream/FileOutputStream for text files and FileReader for anything else)
- (Optional, or maybe not) Wrap a buffer around this stream (Using BufferedReader) to improve performance (unless you somehow want to read each byte on its own and even then the system call overhead would kill your performance – Remember that for every read made in User Space, makes a System Call to the OS in Kernel Space, since only the OS has access to I/O)
- Use this Stream to read or write data to or from the file
So let’s head into some code:
First try at I/O operations with Files in Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public static void main(String[] args) throws IOException { String fileSeparator = System.getProperty("file.separator"); File starcraftDump = new File(fileSeparator + "NewDirectoryInTheVoid" + fileSeparator + "ProtossOP"); File starcraftImage = new File(fileSeparator + "NewDirectoryInTheVoid" + fileSeparator + "darkTemplar.jpg"); readTextFile(starcraftDump); readImageFile(starcraftImage); } public static void readTextFile(File fooBar) throws IOException, FileNotFoundException { FileReader inputSR = new FileReader(fooBar); BufferedReader buffReader = new BufferedReader(inputSR); String fooBarLine = buffReader.readLine(); while (fooBarLine != null) { System.out.println(fooBarLine); fooBarLine = buffReader.readLine(); } buffReader.close(); } public static void readImageFile(File fooBarImage) throws IOException { FileInputStream fileIS = new FileInputStream(fooBarImage); InputStreamReader inputSR = new InputStreamReader(fileIS); BufferedReader buffReader = new BufferedReader(inputSR); String fooBarLine = buffReader.readLine(); while (fooBarLine != null) { System.out.println(fooBarLine); fooBarLine = buffReader.readLine(); } buffReader.close(); } |
Well, this looks great doesn’t it! We are reading from a file, and printing out whatever we read… There is however a few tweaks we can do. First off, we are using InputStreamReader on an image, whereas you are supposed to use it for reading text and hence we are outputting gibberish during our readImageFile() method. This is not very helpful. Secondly we are doing an Output every time we want to print a line in our readTextFile() method. So how about we modify a few things:
- Instead of just reading and printing out gibberish from the image, let us copy it somewhere else!
- Use a buffer for the output too!
- Try a different way for reading / writing text files!
Hence let’s once again try to code this out.
Second try at I/O operations with Files in Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
public static void main(String[] args) throws IOException { String fileSeparator = System.getProperty("file.separator"); File starcraftDump = new File(fileSeparator + "DirectoryInTheVoid" + fileSeparator + "ProtossOP"); File starcraftImage = new File(fileSeparator + "DirectoryInTheVoid" + fileSeparator + "darkTemplar.jpg"); File newStarcraftDump = new File(fileSeparator + "NewDirectoryInTheVoid" + fileSeparator + "ProtossOP"); File newStarcraftImage = new File(fileSeparator + "NewDirectoryInTheVoid" + fileSeparator + "darkTemplar.jpg"); newStarcraftDump.createNewFile(); newStarcraftImage.createNewFile(); readWriteTextFile(starcraftDump, newStarcraftDump); readWriteTextFileWithStreams(starcraftDump, newStarcraftDump); copyImageFile(starcraftImage, newStarcraftImage); } public static void readWriteTextFile(File readMe, File writeMe) throws IOException, FileNotFoundException { FileReader inputFR = new FileReader(readMe); BufferedReader buffReader = new BufferedReader(inputFR); FileWriter outputFR = new FileWriter(writeMe); BufferedWriter buffWriter = new BufferedWriter(outputFR); String fooBarLine; while ((fooBarLine = buffReader.readLine()) != null) { buffWriter.write(fooBarLine); } buffReader.close(); buffWriter.close(); } public static void readWriteTextFileWithStreams(File readMe, File writeMe) throws IOException, FileNotFoundException { FileInputStream fileIS = new FileInputStream(readMe); InputStreamReader inputSR = new InputStreamReader(fileIS); BufferedReader buffReader = new BufferedReader(inputSR); FileOutputStream fileOS = new FileOutputStream(writeMe); OutputStreamWriter outputSR = new OutputStreamWriter(fileOS); BufferedWriter buffWriter = new BufferedWriter(outputSR); String fooBarLine; while ((fooBarLine = buffReader.readLine()) != null) { buffWriter.write(fooBarLine); } buffReader.close(); buffWriter.close(); } public static void copyImageFile(File readMe, File writeMe) throws IOException { FileInputStream fileIS = new FileInputStream(readMe); BufferedInputStream buffIS = new BufferedInputStream(fileIS); FileOutputStream fileOS = new FileOutputStream(writeMe); BufferedOutputStream buffOS = new BufferedOutputStream(fileOS); int data; while ((data = buffIS.read()) != -1) { buffOS.write(data); } buffIS.close(); buffOS.close(); } |
Once again after looking at the above piece of code and see the different bunch of Streams, Readers, Writers, intertwined that get you #mindflabergasted… I am going to remind you about the very important concepts:
- Streams – Read/Write binary data one byte at a time – FileInputStream, FileOutputStream
- Readers/Writers – Read/Write from and to text files one char at a time – FileReader, FileWriter, InputStreamReader, OutputStreamWriter
- Buffered – Wraps the above, Read/Write many bytes/chars – BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream
Other notes to be made:
- Almost always use a buffer!!! It is going to impact your performance a lot. Choose your buffer size wisely.
- Do not forget to close() the resources that are using the files (in most cases your buffered wrappers)
- You should properly handle IOException and FileNotFoundExceptions, although I did not
- Putting the read assignment in the while() loop check, is a common use and will do the same thing as declaring it before the loop and changing it at the end (see differences of my first try versus my second try.
This is it! After all this writing I feel a lot more comfortable in my ability to use read write operations with Files in Java and so should you :).
Hope you guys enjoyed it… and I’ll see you guys next time ;D
Latest posts by Ajk (see all)
- Find Median from Numbers Array - January 1, 2018
- Find Whether a Number Can Be the Sum of Two Squares - August 12, 2017
- How to Find Two Primes Whose Sum is Equal to a Number N - April 22, 2017