File I/O in Java
Tags: java
Published: 2021-07-13 18:33:42

###### Content: 
######  a. Reading/Writing to a text file
######  b. The ``file`` class
**What are Streams?**
**Stream** is an object that allows flow of data between your program and I/O devices or some files.
- Two kinds of streams: </br>

1. **inputStream**: if the flow is **into** the program from (keyboard or file), and the operation is called **"Reading from"**.
2. **outputStream**: if the flow is **out of** the program to (screen or file), and the operation is called **"Writing to"**.

- Two kinds of files to deal with:


 
 1. **Text files**: Files contain sequence of characters when viewed in text editors or read by a program, ex: files contain java program.
- They also called **ASCII files**.
- Can be read by human.
- Can move from one computer to other.
- Can read or write to them using text editors.
 1. **Binary files**: Files contain sequence of binary digits.
- Can be read only by programs.
- In java, binary files can move from one type of computer to another.
- Must read or write to them using only by a program.


 ***A. Reading From A text file:***
######Lord Polonius: What do you read, my lord? 
######Hamlet: Words, words, words. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h1uhz3pjyyb3nm07l34.jpg)

The two main stream classes for reading from a text file:
- Scanner
- BufferedReader

a. Using Scanner
Ex:
```java
//Opening an inputStream and convert the file name to FileInputStream object
Scanner inputStream = new Scanner(new FileInputStream("marks.txt"));

        int counter = 0;
        while (inputStream.hasNextInt()) { //Returns true if there is next int in the file
            int number = inputStream.nextInt();  //Scans the next token of the input as an int.
            System.out.println(number);
        }
        inputStream.close();
```
Output:
```
1
2
3
```
- The class Scanner does not care if the stream comes from the the keyboard or from a file.
- The Scanner class has no constructor takes a file name as it's argument (We need to convert the file name to object).
- A richer class to read the files.

b. Using BufferedReader
Ex: 
```java
//The program opens the text file
BufferedReader inputStream = new BufferedReader(new FileReader("quots.txt")); //FileReader to convert the file name to object
        String i= inputStream.readLine();
        while (i!=null){
             System.out.println(i);
        i= inputStream.readLine();
       
        }

```
Output:
```
123 hello
1 23d I am on console!
```
- The ``BufferedReader`` class has no constructor takes a file name as it's argument (We need to convert the file name to object).
- There are **only** two methods to read from the text file: ``readLine`` and ``read``.
- The ``read`` method reads a single character, and returns an ``int`` that corresponds to the character you read.(You need to cast that int to get the character), ex:

```java 
char next = (char)inputStram.read();
```
- To signal the end of the file, the ``readLine`` method returns ``null`` and ``read`` method returns -1.
- Unlike class ``Scanner``, the class ``BufferedReader`` has no 
constructor to deal with numbers. You have to read the numbers as a string then convert the string to a numeric type, ex:
``Integer.parseInt();`` ``Double.pareDouble();``

- If there are multiple numbers in a single line:

 a. Read the line using ``readLine()``
 b. Use ``StringTokenizer`` to decompose the string into tokens.


***B. Writing to a text file:***
The class ``PrintWriter`` is the preferred class to write to a text file.
Ex:

```java
        //Opening the file
     PrintWriter outputStream = new PrintWriter(new FileOutputStream("shahed.txt")); //use FileOutputStream to convert the file name to object

        //writing to the file 
        outputStream.print("this line written from a java program");
        //close the connection
        outputStream.close();
```
Output:

```
this line written from a java program
```
- The program start with **empty** file and if the file shahed.txt already exist, the old content will be lost.
- To test if the file is already exist, we can use the ``File`` class.              
- The ``PrintWriter`` class has no constructor takes a file name as it's argument (We need to convert the file name to object).
- When the program finish writing, it should ***close*** the the stream connected to that file.
- To **flush** the content of the buffer (temporary location for the data to be written) use the method ``flush()``
- The method ``close()`` include an invocation of ``flush()``.
- To append new text to old text, then you have to open the file with the following manner:
```java
PrintWriter outputStreamToAppend = new PrintWriter(new FileOutputStream("shahed.txt", true));
```


In this way the old content will remain and the new content will place after the old content.
- ``PrintWriter`` class throw ``FileNotFoundException`` and it indicates that file can't be created.

***The ``File`` class***
- The ``File`` class constructor takes a string name (***Abstract name***) and checks the properties if that name, ex ``exists`` methods checks if name is exists, and ``isDirectory()`` tests if the name the name of a directory.
ex:
```java
File file = new File ("Fruits.txt");
if (!file.canRead()){
System.out.println("The file can not be read!")
}
```
- Some methods in File class:
   - ``setReadOnly()``
   - ``canWrite()``
   - ``delete()``
   - ``getName()``
   - ``getPath()``
   - ``length()``