YouTip LogoYouTip

Java Files Io

# Java Streams, Files, and IO Streams, Files, and IO (Input/Output) in Java are fundamental for handling data reading and writing. They allow programs to interact with external data sources such as files, network connections, and system inputs. The `java.io` package is a core package in the Java standard library, providing classes for system input and output. It includes tools for handling data streams (byte streams and character streams), file read/write operations, serialization, and data formatting. `java.io` is the foundational package for file operations, stream operations, and low-level IO operations. Streams in the `java.io` package support many formats, such as primitive types, objects, localized character sets, and more. A stream can be understood as a sequence of data. An input stream represents reading data from a source, while an output stream represents writing data to a destination. * * * ## Reading Console Input Java's console input is handled by `System.in`. To obtain a character stream bound to the console, you can wrap `System.in` in a `BufferedReader` object to create a character stream. Here is the basic syntax for creating a `BufferedReader`: ```java BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Once the `BufferedReader` object is created, we can use the `read()` method to read a character from the console, or the `readLine()` method to read a string. * * * ## Reading Multiple Characters from Console To read a character from a `BufferedReader` object, use the `read()` method. Its syntax is: ```java int read() throws IOException Each time the `read()` method is called, it reads one character from the input stream and returns it as an integer value. It returns -1 when the end of the stream is reached. This method throws an `IOException`. The following program demonstrates using the `read()` method to continuously read characters from the console until the user enters 'q'. ## BRRead.java File Code: ```java import java.io.*; public class BRRead{ public static void main(String[]args) throws IOException{ char c; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Enter characters, press 'q' to quit."); do{ c = (char)br.read(); System.out.println(c); }while(c != 'q'); } } The compilation and execution results of the above example are as follows: Enter characters, press 'q' to quit. tutorial r u n o o b q q * * * ## Reading Strings from Console To read a string from standard input, use the `readLine()` method of `BufferedReader`. Its general format is: ```java String readLine() throws IOException The following program reads and displays lines of text until you enter the word "end". ## BRReadLines.java File Code: ```java import java.io.*; public class BRReadLines{ public static void main(String[]args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter 'end' to quit."); do{ str = br.readLine(); System.out.println(str); }while(!str.equals("end")); } } The compilation and execution results of the above example are as follows: Enter lines of text. Enter 'end' to quit. This is line one This is line one This is line two This is line two end end > After JDK 5, we can also use the (#) class to obtain console input. * * * ## Console Output As previously introduced, console output is handled by `print()` and `println()`. These methods are defined by the `PrintStream` class, and `System.out` is a reference to an object of this class. `PrintStream` inherits from the `OutputStream` class and implements the `write()` method. Thus, `write()` can also be used for console output operations. The simplest format for `write()` defined by `PrintStream` is as follows: ```java void write(int byteval) This method writes the low-order eight bits of `byteval` to the stream. ### Example The following example uses `write()` to output the character "A" followed by a newline character to the screen: ## WriteDemo.java File Code: ```java import java.io.*; public class WriteDemo{ public static void main(String[]args){ int b; b = 'A'; System.out.write(b); System.out.write('n'); } } Running the above example outputs the character "A" in the output window. A **Note:** The `write()` method is not commonly used because the `print()` and `println()` methods are more convenient. * * * ## Reading and Writing Files As mentioned earlier, a stream is defined as a sequence of data. Input streams are used to read data from a source, and output streams are used to write data to a destination. The following diagram illustrates the class hierarchy for input and output streams. [!(#)](#) ### Byte Streams (Handling Binary Data) Byte streams are used for handling binary data, such as files, images, videos, etc. | Class Name | Type | Description | | --- | --- | --- | | `InputStream` | Abstract Class (Input Stream) | Superclass for all byte input streams, handles byte input operations. | | `OutputStream` | Abstract Class (Output Stream) | Superclass for all byte output streams, handles byte output operations. | | `FileInputStream` | Input Stream | Reads byte data from a file. | | `FileOutputStream` | Output Stream | Writes byte data to a file. | | `BufferedInputStream` | Input Stream | Provides buffering functionality for byte input streams, improving read efficiency. | | `BufferedOutputStream` | Output Stream | Provides buffering functionality for byte output streams, improving write efficiency. | | `ByteArrayInputStream` | Input Stream | Uses an in-memory byte array as an input source. | | `ByteArrayOutputStream` | Output Stream | Writes data to an in-memory byte array. | | `DataInputStream` | Input Stream | Allows reading Java primitive data types (like `int`, `float`, `boolean`) from an input stream. | | `DataOutputStream` | Output Stream | Allows writing Java primitive data types to an output stream. | | `ObjectInputStream` | Input Stream | Reads serialized objects from an input stream. | | `ObjectOutputStream` | Output Stream | Serializes objects and writes them to an output stream. | | `PipedInputStream` | Input Stream | Used for reading byte data in a pipe, typically used with `PipedOutputStream`. | | `PipedOutputStream` | Output Stream | Used for writing byte data in a pipe, typically used with `PipedInputStream`. | | `FilterInputStream` | Input Stream | Wrapper class for byte input streams, used for filtering other input streams. | | `FilterOutputStream` | Output Stream | Wrapper class for byte output streams, used for filtering other output streams. | | `SequenceInputStream` | Input Stream | Concatenates multiple input streams into a single input stream for processing. | ### Character Streams (Handling Text Data) Character streams are used for handling text data, such as reading and writing strings or files. | Class Name | Type | Description | | --- | --- | --- | | `Reader` | Abstract Class (Input Stream) | Superclass for all character input streams, handles character input operations. | | `Writer` | Abstract Class (Output Stream) | Superclass for all character output streams, handles character output operations. | | `FileReader` | Input Stream | Reads character data from a file. | | `FileWriter` | Output Stream | Writes character data to a file. | | `BufferedReader` | Input Stream | Provides buffering functionality for character input streams, supports line-by-line reading, improving read efficiency. | | `BufferedWriter` | Output Stream | Provides buffering functionality for character output streams, supports line-by-line writing, improving write efficiency. | | `CharArrayReader` | Input Stream | Uses a character array as an input source. | | `CharArrayWriter` | Output Stream | Writes data to a character array. | | `StringReader` | Input Stream | Uses a string as an input source. | | `StringWriter` | Output Stream | Writes data to a string buffer. | | `PrintWriter` | Output Stream | A convenient character output stream that supports automatic flushing and formatted output. | | `PipedReader` | Input Stream | Used for reading character data in a pipe, typically used with `PipedWriter`. | | `PipedWriter` | Output Stream | Used for writing character data in a pipe, typically used with `PipedReader`. | | `LineNumberReader` | Input Stream | A buffered character input stream with line numbers, allowing tracking of the line number being read. | | `PushbackReader` | Input Stream | Allows pushing back characters into the stream after reading them, for re-reading. | ### Utility Classes (Other Important Classes) Utility classes provide support for files, directories, and random file access. | Class Name | Type | Description | | --- | --- | --- | | `File` | File and Directory Operations | Represents a file or directory and provides file operations like creation, deletion, renaming, etc. | | `RandomAccessFile` | Random Access File | Supports random access to files, allowing reading and writing data from any position in the file. | | `Console` | Console Input/Output | Provides input and output support for the system console. | The two important streams to be discussed next are **FileInputStream** and **FileOutputStream**. * * * ## FileInputStream This stream is used to read data from a file. Its object can be created using the `new` keyword. There are multiple constructors available to create an object. You can create an input stream object to read a file using a string filename: ```java InputStream f = new FileInputStream("C:/java/hello"); Alternatively, you can use a `File` object to create an input stream object to read a file. First, we need to create a `File` object using the `File()` constructor: ```java File f = new File("C:/java/hello"); InputStream in = new FileInputStream(f); Once the `InputStream` object is created, you can use the following methods to read from the stream or perform other stream operations. | Method | Description | Example Code | | --- | --- | --- | | `int read()` | Reads a single byte of data, returning an integer between 0 and 255. Returns -1 if the end of the stream is reached. | `int data = inputStream.read();` | | `int read(byte[] b)` | Reads bytes from the input stream and stores them in the byte array `b`, returning the actual number of bytes read. Returns -1 if the end of the stream is reached. | `byte[] buffer = new byte; int bytesRead = inputStream.read(buffer);` | | `int read(byte[] b, int off, int len)` | Reads up to `len` bytes from the input stream and stores them in the byte array `b` starting at offset `off`, returning the actual number of bytes read. Returns -1 if the end of the stream is reached. | `byte[] buffer = new byte; int bytesRead = inputStream.read(buffer, 0, buffer.length);` | | `long skip(long n)` | Skips and discards `n` bytes from the input stream, returning the actual number of bytes skipped. | `long skippedBytes = inputStream.skip(100);` | | `int available()` | Returns the number of bytes that can be read (without blocking). | `int availableBytes = inputStream.available();` | | `void close()` | Closes the input stream and releases all resources associated with it. | `inputStream.close();` | | `void mark(int readlimit)` | Sets a mark at the current position in the stream, with `readlimit` being the maximum number of bytes that can be read before the mark becomes invalid. | `inputStream.mark(1024);` | | `void reset()` | Resets the stream to the last marked position. Throws `IOException` if no mark has been set or the mark has become invalid. | `inputStream.reset();` | | `boolean markSupported()` | Checks if the current input stream supports the `mark()` and `reset()` operations. | `boolean isMarkSupported = inputStream.markSupported();` | Besides `InputStream`, there are other input streams. For more details, refer to the links below: * * * ## FileOutputStream This class is used to create a file and write data to it. If the target file does not exist before the stream opens it for output, the stream will create the file. There are two constructors available to create a `FileOutputStream` object. Create an output stream object using a string filename: ```java OutputStream f = new FileOutputStream("C:/java/hello") Alternatively, you can use a `File` object to create an output stream to write to a file. First, we need to create a `File` object using the `File()` constructor: ```java File f = new File("C:/java/hello"); OutputStream fOut = new FileOutputStream(f); Once the `OutputStream` object is created, you can use the following methods to write to the stream or perform other stream operations. | Method | Description | Example Code | | --- | --- | --- | | `void write(int b)` | Writes the specified byte to the output stream. The low 8 bits of `b` will be written to the stream. | `outputStream.write(255);` | | `void write(byte[] b)` | Writes all bytes from the byte array `b` to the output stream. | `byte[] data = "Hello".getBytes(); outputStream.write(data);` | | `void write(byte[] b, int off, int len)` | Writes `len` bytes from the byte array `b` starting at offset `off` to the output stream. | `byte[] data = "Hello".getBytes(); outputStream.write(data, 0, data.length);` | | `void flush()` | Flushes the output stream and forces any buffered output bytes to be written out, ensuring data is immediately written to the destination. | `outputStream.flush();` | | `void close()` | Closes the output stream and releases all resources associated with it. No further writes can be performed after closing. | `outputStream.close();` | Besides `OutputStream`, there are other output streams. For more details, refer to the links below: ### Example Here is an example demonstrating the usage of `InputStream` and `OutputStream`: ## fileStreamTest.java File Code: ```java import java.io.*; public class fileStreamTest{ public static void main(String[]args){ try{ byte bWrite[] = {11, 21, 3, 40, 5}; OutputStream os = new FileOutputStream("test.txt"); for(int x = 0; x<bWrite.length; x++){ os.write(bWrite); } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for(int i = 0; i<size; i++){ System.out.print((char)is.read() + ""); } is.close(); }catch(IOException e){ System.out.print("Exception"); } } } The above program first creates the file `test.txt` and writes the given numbers in binary form to the file, while also outputting them to the console. Since the above code uses binary writing, it may result in garbled characters. You can use the following code example to solve the garbled character issue: ## fileStreamTest2.java File Code: ```java import java.io.*; public class fileStreamTest2{ public static void main(String[]args) throws IOException{ File f = new File("a.txt"); FileOutputStream fop = new FileOutputStream(f); OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8"); writer.append("Chinese input"); writer.append("rn"); writer.append("English"); writer.close(); fop.close(); FileInputStream fip = new FileInputStream(f); InputStreamReader reader = new InputStreamReader(fip, "UTF-8"); StringBuffer sb = new StringBuffer(); while(reader.ready()){ sb.append((char)reader.read()); } System.out.println(sb.toString()); reader.close(); fip.close(); } } * * * ## Files and I/O There are some other classes related to files and I/O that we also need to know: * * * ## Directories in Java ### Creating a Directory: The `File` class has two methods for creating directories: * The **mkdir()** method creates a directory, returning `true` on success and `false` on failure. Failure indicates that the path specified by the `File` object already exists, or that the directory cannot be created because the entire path does not yet exist. * The **mkdirs()** method creates a directory and all its necessary parent directories. The following example creates the directory "/tmp/user/java/bin": ## CreateDir.java File Code: ```java import java.io.File; public class CreateDir{ public static void main(String[]args){ String dirname = "/tmp/user/java/bin"; File d = new File(dirname); d.mkdirs(); } } Compile and execute the above code to create the directory "/tmp/user/java/bin". **Note:** Java automatically distinguishes file path separators according to convention on UNIX and Windows. If you use the separator (/) in the Windows version of Java, the path will still be parsed correctly. * * * ## Reading a Directory A directory is essentially a `File` object that contains other files and folders. If you create a `File` object and it represents a directory, calling the `isDirectory()` method will return `true`. You can extract a list of files and folders it contains by calling the `list()` method on that object. The following example demonstrates how to use the `list()` method to check the contents of a directory: ## DirList.java File Code: ```java import java.io.File; public class DirList{ public static void main(String args[]){ String dirname = "/tmp"; File f1 = new File(dirname); if(f1.isDirectory()){ System.out.println("Directory " + dirname); String s[] = f1.list(); for(int i = 0; i<s.length; i++){ File f = new File(dirname + "/" + s); if(f.isDirectory()){ System.out.println(s + " is a directory"); }else{ System.out.println(s + " is a file"); } } }else{ System.out.println(dirname + " is not a directory"); } } } The compilation and execution results of the above example are as follows: Directory /tmp bin is a directory lib is a directory demo is a directory test.txt is a file README is a file index.html is a file include is a directory * * * ## Deleting a Directory or File To delete a file, you can use the **java.io.File.delete()** method. The following code will delete the directory **/tmp/java/**. Note that when deleting a directory, you must ensure that there are no other files in that directory for it to be deleted correctly; otherwise, the deletion will fail. Test directory structure: /tmp/java/ |-- 1.log |-- test ## DeleteFileDemo.java File Code: ```java import java.io.File; public class DeleteFileDemo{ public static void main(String[]args){ File folder = new File("/tmp/java/"); deleteFolder(folder); } public static void deleteFolder(File folder){ File[]files = folder.listFiles(); if(files != null){ for(File f : files){ if(f.isDirectory()){ deleteFolder(f); }else{ f.delete(); } } } folder.delete(); } }
← Java ExceptionsJava Methods β†’