# 158. Read N Characters Given Read4 II - Call multiple times

### Description

Given a file and assume that you can only read the file using a given method `read4`, implement a method `read` to read *n* characters. **Your method `read` may be called multiple times.**

**Method read4:**

The API `read4` reads 4 consecutive characters from the file, then writes those characters into the buffer array `buf`.

The return value is the number of actual characters read.

Note that `read4()` has its own file pointer, much like `FILE *fp` in C.

**Definition of read4:**

> Parameter: char\[] buf4
>
> Returns: int
>
> Note: buf4\[] is destination not source, the results from read4 will be copied to buf4\[]

Below is a high level example of how `read4` works:

![](https://assets.leetcode.com/uploads/2020/07/01/157_example.png)

```
File file("abcde"); // File is "abcde", initially file pointer (fp) points to 'a'
char[] buf = new char[4]; // Create buffer with enough space to store characters
read4(buf4); // read4 returns 4. Now buf = "abcd", fp points to 'e'
read4(buf4); // read4 returns 1. Now buf = "e", fp points to end of file
read4(buf4); // read4 returns 0. Now buf = "", fp points to end of file
```

**Method read:**

By using the `read4` method, implement the method `read` that reads n characters from the file and store it in the buffer array `buf`. Consider that you **cannot** manipulate the file directly.

The return value is the number of actual characters read.

**Definition of read:**

> Parameters: char\[] buf, int n
>
> Returns: int
>
> Note: buf\[] is destination not source, you will need to write the results to buf\[]

### Constraints

### Approach

### Links

* GeeksforGeeks
* [Leetcode](https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/)
* ProgramCreek
* YouTube

### **Examples**

{% tabs %}
{% tab title="Example 1" %}
**Input:**

"abc"

\[1, 2, 1]

**Output:**

\["a", "bc", ""]

**Explanation:**

File file("abc");

Solution sol;

// Assume buf is allocated and guaranteed to have enough space for storing all characters from the file.

sol.read(buf, 1); // After calling your read method, buf should contain "a". We read a total of 1 character from the file, so return 1.

sol.read(buf, 2); // Now buf should contain "bc". We read a total of 2 characters from the file, so return 2.

sol.read(buf, 1); // We have reached the end of file, no more characters can be read. So return 0.
{% endtab %}

{% tab title="Example 2" %}
**Input:**

"abc"

\[4,1]

**Output:**

\["abc", ""]

**Explanation:**

File file("abc");

Solution sol;

sol.read(buf, 4); // After calling your read method, buf should contain "abc". We read a total of 3 characters from the file, so return 3.

sol.read(buf, 1); // We have reached the end of file, no more characters can be read. So return 0.
{% endtab %}
{% endtabs %}

### **Solutions**

{% tabs %}
{% tab title="Solution 1" %}

```java
/**
 * Time complexity : 
 * Space complexity : 
 */

/**
 * The read4 API is defined in the parent class Reader4.
 *     int read4(char[] buf4); 
 */

public class Solution extends Reader4 {
    /**
     * @param buf Destination buffer
     * @param n   Number of characters to read
     * @return    The number of actual characters read
     */
    
    private boolean eof = false;
    private char[] buf4 = new char[4];
    
    public int read(char[] buf, int n) {
        int bufSize = 0;
        
        for(int i = 0; i < 4; i++) {
            if(bufSize == n) {
                return bufSize;
            }
            if(buf4[i] != '\u0000') {
                buf[bufSize++] = buf4[i];
                buf4[i] = '\u0000';
            }
        }
        
        while(!eof && bufSize < n) {
            int size = read4(buf4);
            
            eof = size < 4;

            size = Math.min(size, n-bufSize);

            for(int i = 0; i < size; i++) {
                buf[bufSize++] = buf4[i];
                buf4[i] = '\u0000';
            }
        }
        
        return bufSize;
    }
}
```

{% endtab %}

{% tab title="Solution 2" %}

```java
/**
 * Time complexity : 
 * Space complexity : 
 */
 
/**
 * The read4 API is defined in the parent class Reader4.
 *     int read4(char[] buf4); 
 */

public class Solution extends Reader4 {
    /**
     * @param buf Destination buffer
     * @param n   Number of characters to read
     * @return    The number of actual characters read
     */
    
    private char[] buf4 = new char[4];
    private int readIdx = 0;
    private int size = 0;
    
    public int read(char[] buf, int n) {
        int writeIdx = 0;
        
        while(readIdx < size && writeIdx < n) {
            buf[writeIdx++] = buf4[readIdx++];
        }
        
        while(writeIdx < n) {
            size = read4(buf4);
            
            if(size == 0) break;
            
            readIdx = 0;
            while(readIdx < size && writeIdx < n) {
                buf[writeIdx++] = buf4[readIdx++];
            }
        }
        
        return writeIdx;
    }
}
```

{% endtab %}
{% endtabs %}

### **Follow up**

*
