Java IO Tutorial

How to read and parse CSV file in Java

A CSV file

This article shows how to read and parse a comma-separated values (CSV) file.

Topics:

  1. CSV file and RFC 4180
  2. OpenCSV – Read and Parse CSV file
  3. OpenCSV – Convert CSV file to Object
  4. Parse CSV file Challenges – Embedded commas, double quotes, and line breaks
  5. Single class to read and parse a CSV file
  6. String#split to parse a CSV file

1. CSV file and RFC 4180.

A comma-separated values (CSV) file is a standard text file which uses a comma to separate value. Each line of the file consists of one or more fields, separated by commas. Each field may or may not be enclosed in double-quotes.


1995,Java,James Gosling
"1995","Java","James Gosling"

The RFC 4180 defines the format or definitions of a CSV file or text/csv file.

2. OpenCSV – Read and Parse CSV file.

2.1 The OpenCSV is simple and easy to use CSV parser for Java.

pom.xml

  <dependency>
      <groupId>com.opencsv</groupId>
      <artifactId>opencsv</artifactId>
      <version>5.3</version>
  </dependency>

2.2 However, the opencsv.jar has the following dependencies like commons-lang3.jar, commons-text.jar, commons-beanutils.jar, commons-logging.jar and commons-collections4:jar.

Terminal

[INFO] \- com.opencsv:opencsv:jar:5.3:compile
[INFO]    +- org.apache.commons:commons-lang3:jar:3.11:compile
[INFO]    +- org.apache.commons:commons-text:jar:1.9:compile
[INFO]    +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
[INFO]    |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO]    |  \- commons-collections:commons-collections:jar:3.2.2:compile
[INFO]    \- org.apache.commons:commons-collections4:jar:4.4:compile

P.S The total file size of OpenCSV and its’ dependencies is around 2M+.

2.3 The OpenCSV examples to read or parse a CSV file.

Read all and returns a List<String[]>.


  try (CSVReader reader = new CSVReader(new FileReader("file.csv"))) {
      List<String[]> r = reader.readAll();
      r.forEach(x -> System.out.println(Arrays.toString(x)));
  }

Read line by line and turns line into a String[].


  try (CSVReader reader = new CSVReader(new FileReader("file.csv"))) {
      String[] lineInArray;
      while ((lineInArray = reader.readNext()) != null) {
          System.out.println(lineInArray[0] + lineInArray[1] + "etc...");
      }
  }

A complete OpenCSV example to parse a CSV file.

c:\\test\\csv\\country.csv

"1.0.0.0","1.0.0.255","AU","Australia"
"1.0.1.0","1.0.3.255","CN","China"
"1.0.4.0","1.0.7.255","AU","Australia"
"1.0.128.0","1.0.255.255","TH","Thailand"
OpenCsvExample.java

package com.mkyong.io.csv.opencsv;

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class OpenCsvExample {

    public static void main(String[] args) throws IOException, CsvException {

        String fileName = "c:\\test\\csv\\country.csv";
        try (CSVReader reader = new CSVReader(new FileReader(fileName))) {
            List<String[]> r = reader.readAll();
            r.forEach(x -> System.out.println(Arrays.toString(x)));
        }

    }

}

Output

Terminal

[1.0.0.0, 1.0.0.255, AU, Australia]
[1.0.1.0, 1.0.3.255, CN, China]
[1.0.4.0, 1.0.7.255, AU, Australia]
[1.0.128.0, 1.0.255.255, TH, Thailand]

2.4 It is common to use the semicolon ; as the separator. This OpenCSV example shows how to parse a CSV file using a custom separator ; and skip the first line.


  CSVParser csvParser = new CSVParserBuilder().withSeparator(';').build(); // custom separator
  try(CSVReader reader = new CSVReaderBuilder(
          new FileReader(fileName))
          .withCSVParser(csvParser)   // custom CSV parser
          .withSkipLines(1)           // skip the first line, header info
          .build()){
      List<String[]> r = reader.readAll();
      r.forEach(x -> System.out.println(Arrays.toString(x)));
  }

Note
The use of semicolon ; as the separator is not RFC 4180 compliant. However, it’s common to see semicolon separators in the CSV files; not everyone follows the RFC.

3. OpenCSV – Convert CSV file to Object.

The OpenCSV also support read or parse a CSV file into a Java object directly.

3.1 This example read a CSV file and map it to a Country object via the @CsvBindByPosition.

c:\\test\\csv\\country.csv

"1.0.0.0","1.0.0.255","AU","Australia"
"1.0.1.0","1.0.3.255","CN","China"
"1.0.4.0","1.0.7.255","AU","Australia"
"1.0.128.0","1.0.255.255","TH","Thailand"
Country.java

package com.mkyong.io.csv.opencsv;

import com.opencsv.bean.CsvBindByPosition;

public class Country {

    @CsvBindByPosition(position = 0)
    private String startIp;

    @CsvBindByPosition(position = 1)
    private String endIp;

    @CsvBindByPosition(position = 2)
    private String countryCode;

    @CsvBindByPosition(position = 3)
    private String country;

    //  getters, setters, toString
}
OpenCsvExample.java

package com.mkyong.io.csv.opencsv;

import com.opencsv.bean.CsvToBeanBuilder;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class OpenCsvExample {

    public static void main(String[] args) throws IOException {

        String fileName = "c:\\test\\csv\\country.csv";

        List<Country> beans = new CsvToBeanBuilder(new FileReader(fileName))
                .withType(Country.class)
                .build()
                .parse();

        beans.forEach(System.out::println);

    }

}

Output

Terminal

Country{startIp='1.0.0.0', endIp='1.0.0.255', countryCode='AU', country='Australia'}
Country{startIp='1.0.1.0', endIp='1.0.3.255', countryCode='CN', country='China'}
Country{startIp='1.0.4.0', endIp='1.0.7.255', countryCode='AU', country='Australia'}
Country{startIp='1.0.128.0', endIp='1.0.255.255', countryCode='TH', country='Thailand'}

3.2 If the CSV file containing header info, we also can use @CsvBindByName to map the CSV file to a Java object.

c:\\test\\csv\\country.csv

start ip,end ip,country code, country
"1.0.0.0","1.0.0.255","AU","Australia"
"1.0.1.0","1.0.3.255","CN","China"
"1.0.4.0","1.0.7.255","AU","Australia"
"1.0.128.0","1.0.255.255","TH","Thailand"
Country.java

package com.mkyong.io.csv.opencsv;

import com.opencsv.bean.CsvBindByName;

public class Country {

    @CsvBindByName(column = "start ip")
    private String startIp;

    @CsvBindByName(column = "end ip")
    private String endIp;

    @CsvBindByName(column = "country code")
    private String countryCode;

    @CsvBindByName
    private String country;

    //  getters, setters, toString
}

Output

Terminal

Country{startIp='1.0.0.0', endIp='1.0.0.255', countryCode='AU', country='Australia'}
Country{startIp='1.0.1.0', endIp='1.0.3.255', countryCode='CN', country='China'}
Country{startIp='1.0.4.0', endIp='1.0.7.255', countryCode='AU', country='Australia'}
Country{startIp='1.0.128.0', endIp='1.0.255.255', countryCode='TH', country='Thailand'}

Note
For more OpenCSV examples, please check the OpenCSV official documentation

4. CSV and embedded commas, double quotes, and line breaks

4.1 The RFC 4180 describes the definitions of the CSV file formats, the rule 1-5 are some basic and easy to implement, the real challenges are the rule 6 and 7.


6. Fields containing line breaks (CRLF), double quotes, and commas
     should be enclosed in double-quotes.  For example:

     "aaa","b CRLF
     bb","ccc" CRLF
     zzz,yyy,xxx

7.  If double-quotes are used to enclose fields, then a double-quote
     appearing inside a field must be escaped by preceding it with
     another double quote.  For example:

     "aaa","b""bb","ccc"

4.2 Table to CVS file.

Make Model Description Price
Dell P3421W Dell 34, Curved, USB-C Monitor 2499.00
Dell Alienware 38 Curved "Gaming Monitor" 6699.00
Samsung 49" Dual QHD, QLED, HDR1000 6199.00
Samsung Promotion! Special Price
49" Dual QHD, QLED, HDR1000
4999.00

The above table may be represented in CSV format as follows:

monitor.csv

Make,Model,Description,Price
Dell,P3421W,"Dell 34, Curved, USB-C Monitor",2499.00
Dell,"","Alienware 38 Curved ""Gaming Monitor""",6699.00
Samsung,,"49"" Dual QHD, QLED, HDR1000",6199.00
Samsung,,"Promotion! Special Price
49"" Dual QHD, QLED, HDR1000",4999.00

4.3 Let test the above CSV file with the OpenCSV again, and review the result:


package com.mkyong.io.csv.opencsv;

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class OpenCsvExample {

    public static void main(String[] args) throws IOException, CsvException {

        String fileName = "c:\\test\\csv\\monitor.csv";

        List<String[]> r;
        try (CSVReader reader = new CSVReader(new FileReader(fileName))) {
            r = reader.readAll();
        }

        int listIndex = 0;
        for (String[] arrays : r) {
            System.out.println("\nString[" + listIndex++ + "] : " + Arrays.toString(arrays));

            int index = 0;
            for (String array : arrays) {
                System.out.println(index++ + " : " + array);
            }

        }
    }

}

Output

Terminal

String[0] : [Make, Model, Description, Price]
0 : Make
1 : Model
2 : Description
3 : Price

String[1] : [Dell, P3421W, Dell 34, Curved, USB-C Monitor, 2499.00]
0 : Dell
1 : P3421W
2 : Dell 34, Curved, USB-C Monitor
3 : 2499.00

String[2] : [Dell, , Alienware 38 Curved "Gaming Monitor", 6699.00]
0 : Dell
1 :
2 : Alienware 38 Curved "Gaming Monitor"
3 : 6699.00

String[3] : [Samsung, , 49" Dual QHD, QLED, HDR1000, 6199.00]
0 : Samsung
1 :
2 : 49" Dual QHD, QLED, HDR1000
3 : 6199.00

String[4] : [Samsung, , Promotion! Special Price
49" Dual QHD, QLED, HDR1000, 4999.00]
0 : Samsung
1 :
2 : Promotion! Special Price
49" Dual QHD, QLED, HDR1000
3 : 4999.00

The above output is a perfect, exact match.

5. Single class to read and parse a CSV file.

5.1 If you don’t want to download the OpenCSV library due to the file size of too many dependencies, below is my single class implementation to parse a CSV file.

The same CSV file containing embedded commas, double quotes, and line breaks.

monitor.csv

Make,Model,Description,Price
Dell,P3421W,"Dell 34, Curved, USB-C Monitor",2499.00
Dell,"","Alienware 38 Curved ""Gaming Monitor""",6699.00
Samsung,,"49"" Dual QHD, QLED, HDR1000",6199.00
Samsung,,"Promotion! Special Price
49"" Dual QHD, QLED, HDR1000",4999.00

A single class implementation to parse the above CSV file. Read comments for self-explanatory.

CsvParserSimple.java

package com.mkyong.io.csv;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class CsvParserSimple {

    private static final char DEFAULT_SEPARATOR = ',';
    private static final char DOUBLE_QUOTES = '"';
    private static final char DEFAULT_QUOTE_CHAR = DOUBLE_QUOTES;
    private static final String NEW_LINE = "\n";

    private boolean isMultiLine = false;
    private String pendingField = "";
    private String[] pendingFieldLine = new String[]{};

    public static void main(String[] args) throws Exception {

        // loads CSV file from the resource folder.
        URL resource = CsvParserSimple.class.getClassLoader().getResource("csv/monitor.csv");
        File file = Paths.get(resource.toURI()).toFile();

        CsvParserSimple obj = new CsvParserSimple();
        List<String[]> result = obj.readFile(file, 1);

        int listIndex = 0;
        for (String[] arrays : result) {
            System.out.println("\nString[" + listIndex++ + "] : " + Arrays.toString(arrays));

            int index = 0;
            for (String array : arrays) {
                System.out.println(index++ + " : " + array);
            }

        }

    }

    public List<String[]> readFile(File csvFile) throws Exception {
        return readFile(csvFile, 0);
    }

    public List<String[]> readFile(File csvFile, int skipLine)
        throws Exception {

        List<String[]> result = new ArrayList<>();
        int indexLine = 1;

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {

            String line;
            while ((line = br.readLine()) != null) {

                if (indexLine++ <= skipLine) {
                    continue;
                }

                String[] csvLineInArray = parseLine(line);

                if (isMultiLine) {
                    pendingFieldLine = joinArrays(pendingFieldLine, csvLineInArray);
                } else {

                    if (pendingFieldLine != null && pendingFieldLine.length > 0) {
                        // joins all fields and add to list
                        result.add(joinArrays(pendingFieldLine, csvLineInArray));
                        pendingFieldLine = new String[]{};
                    } else {
                        // if dun want to support multiline, only this line is required.
                        result.add(csvLineInArray);
                    }

                }


            }
        }

        return result;
    }

    public String[] parseLine(String line) throws Exception {
        return parseLine(line, DEFAULT_SEPARATOR);
    }

    public String[] parseLine(String line, char separator) throws Exception {
        return parse(line, separator, DEFAULT_QUOTE_CHAR).toArray(String[]::new);
    }

    private List<String> parse(String line, char separator, char quoteChar)
        throws Exception {

        List<String> result = new ArrayList<>();

        boolean inQuotes = false;
        boolean isFieldWithEmbeddedDoubleQuotes = false;

        StringBuilder field = new StringBuilder();

        for (char c : line.toCharArray()) {

            if (c == DOUBLE_QUOTES) {               // handle embedded double quotes ""
                if (isFieldWithEmbeddedDoubleQuotes) {

                    if (field.length() > 0) {       // handle for empty field like "",""
                        field.append(DOUBLE_QUOTES);
                        isFieldWithEmbeddedDoubleQuotes = false;
                    }

                } else {
                    isFieldWithEmbeddedDoubleQuotes = true;
                }
            } else {
                isFieldWithEmbeddedDoubleQuotes = false;
            }

            if (isMultiLine) {                      // multiline, add pending from the previous field
                field.append(pendingField).append(NEW_LINE);
                pendingField = "";
                inQuotes = true;
                isMultiLine = false;
            }

            if (c == quoteChar) {
                inQuotes = !inQuotes;
            } else {
                if (c == separator && !inQuotes) {  // if find separator and not in quotes, add field to the list
                    result.add(field.toString());
                    field.setLength(0);             // empty the field and ready for the next
                } else {
                    field.append(c);                // else append the char into a field
                }
            }

        }

        //line done, what to do next?
        if (inQuotes) {
            pendingField = field.toString();        // multiline
            isMultiLine = true;
        } else {
            result.add(field.toString());           // this is the last field
        }

        return result;

    }

    private String[] joinArrays(String[] array1, String[] array2) {
        return Stream.concat(Arrays.stream(array1), Arrays.stream(array2))
                .toArray(String[]::new);
    }
}

Output.

Terminal

String[0] : [Dell, P3421W, Dell 34, Curved, USB-C Monitor, 2499.00]
0 : Dell
1 : P3421W
2 : Dell 34, Curved, USB-C Monitor
3 : 2499.00

String[1] : [Dell, , Alienware 38 Curved "Gaming Monitor", 6699.00]
0 : Dell
1 :
2 : Alienware 38 Curved "Gaming Monitor"
3 : 6699.00

String[2] : [Samsung, , 49" Dual QHD, QLED, HDR1000, 6199.00]
0 : Samsung
1 :
2 : 49" Dual QHD, QLED, HDR1000
3 : 6199.00

String[3] : [Samsung, , Promotion! Special Price
49" Dual QHD, QLED, HDR1000, 4999.00]
0 : Samsung
1 :
2 : Promotion! Special Price
49" Dual QHD, QLED, HDR1000
3 : 4999.00

The output is correct.

5.3 Read below unit tests for a different type of CSV file.

CsvParserSimpleTest.java

package com.mkyong.io.csv;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CsvParserSimpleTest {

    private CsvParserSimple parser = new CsvParserSimple();
    // OpenCSV
    //private CSVParser parser = new CSVParser();

    @ParameterizedTest(name = "#{index} - Run test with args={0}")
    @ValueSource(strings = {
            "\"aa\",\"bb\",\"cc\",\"dd\",\"ee\"",
            "aa,bb,cc,dd,ee",
            "aa,bb,\"cc\",dd,ee"
    }
    )
    void test_csv_line_default(String line) throws Exception {
        String[] result = parser.parseLine(line);
        assertEquals(5, result.length);
        assertEquals("aa", result[0]);
        assertEquals("bb", result[1]);
        assertEquals("cc", result[2]);
        assertEquals("dd", result[3]);
        assertEquals("ee", result[4]);
    }

    @ParameterizedTest(name = "#{index} - Run test with args={0}")
    @ValueSource(strings = {
            "\"aa\",\"\",\"\",\"\",\"\"",
            "aa,,,,",
            "aa,,\"\",,"
    }
    )
    void test_csv_line_empty(String line) throws Exception {
        String[] result = parser.parseLine(line);
        assertEquals(5, result.length);
        assertEquals("aa", result[0]);
        assertEquals("", result[1]);
        assertEquals("", result[2]);
        assertEquals("", result[3]);
        assertEquals("", result[4]);
    }

    // RFC 4180 require comma as separator, but in real life , it can be a semicolon,
    // not everyone follows RFC.
    @ParameterizedTest(name = "#{index} - Run test with args={0}")
    @ValueSource(strings = {
            "\"aa\";\"bb\";\"cc\";\"dd\";\"ee\"",
            "aa;bb;cc;dd;ee",
            "aa;bb;\"cc\";dd;ee"
    }
    )
    void test_csv_line_custom_separator(String line) throws Exception {
        String[] result = parser.parseLine(line, ';');
        assertEquals(5, result.length);
        assertEquals("aa", result[0]);
        assertEquals("bb", result[1]);
        assertEquals("cc", result[2]);
        assertEquals("dd", result[3]);
        assertEquals("ee", result[4]);
    }

    @ParameterizedTest(name = "#{index} - Run test with args={0}")
    @ValueSource(strings = {
            "\"Australia\",\"11 Lakkari Cl, Taree, NSW 2430\"",
            "Australia,\"11 Lakkari Cl, Taree, NSW 2430\""
    }
    )
    void test_csv_line_contain_comma_in_field(String line) throws Exception {

        String[] result = parser.parseLine(line);

        assertEquals(2, result.length);
        assertEquals("Australia", result[0]);
        assertEquals("11 Lakkari Cl, Taree, NSW 2430", result[1]);

    }

    @Test
    void test_csv_line_contain_double_quotes_in_field() throws Exception {

        String line = "\"Australia\",\"51 Maritime Avenue, \"\"Western Australia\"\", 6286\"";
        String[] result = parser.parseLine(line);

        assertEquals(2, result.length);
        assertEquals("Australia", result[0]);
        assertEquals("51 Maritime Avenue, \"Western Australia\", 6286", result[1]);

    }

    @Test
    void test_csv_line_contain_double_quotes_in_field_2() throws Exception {

        String line = "Australia,Welcome to \"\"Western Australia\"\"";
        String[] result = parser.parseLine(line);

        assertEquals(2, result.length);
        assertEquals("Australia", result[0]);
        assertEquals("Welcome to \"Western Australia\"", result[1]);

    }

    /*
    private File getFileFromTestResourcesFolder(String fileName) throws URISyntaxException {
        // get uri from the test resources folder.
        URL resource = CsvParserMyImplTest.class.getClassLoader().getResource(fileName);
        File file = Paths.get(resource.toURI()).toFile();
        return file;
    }*/
}

Parse CSV Unit Tests

Review the result and the unit tests; the CsvParserSimple should read or parse most of the standard CSV files.

6. String#split to parse a CSV file.

6.1 Q: Can I use the String#split to parse a simple CSV file?
Yes, if you are sure, the CSV file format is plain simple and doesn’t contain any embedded commas, double quotes, and line breaks, as described in the above parse CSV file Challenges.

country.csv

"1.0.0.0","1.0.0.255","AU","Australia"
"1.0.1.0","1.0.3.255","CN","China"
"1.0.4.0","1.0.7.255","AU","Australia"
"1.0.128.0","1.0.255.255","TH","Thailand"

6.2 Java 8 stream and split example to parse the above CSV file.


  List<String[]> collect =
          Files.lines(Paths.get("c:\\test\\csv\\country.csv"))
                .map(line -> line.split(","))
                .collect(Collectors.toList());

Output

Terminal

["1.0.0.0", "1.0.0.255", "AU", "Australia"]
["1.0.1.0", "1.0.3.255", "CN", "China"]
["1.0.4.0", "1.0.7.255", "AU", "Australia"]
["1.0.128.0", "1.0.255.255", "TH", "Thailand"]

6.3 Here is the old school style.


  String line;
  try (BufferedReader br = new BufferedReader(
          new FileReader("c:\\test\\csv\\country.csv"))) {

      while ((line = br.readLine()) != null) {

          // split by a comma separator
          String[] split = line.split(",");
          System.out.println("\nLength : " + split.length);
          System.out.println("split[0] : " + split[0]);
          System.out.println("split[1] : " + split[1]);
          System.out.println("split[2] : " + split[2]);
          System.out.println("split[3] : " + split[3]);
      }

  } catch (IOException e) {
      e.printStackTrace();
  }

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-io/csv

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
23 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Ömer Hakan Bilici
7 years ago

Thanks. Note that OpenCSV Example part is enough for most cases. I think you should move this part to start of this post.

Areizero Developer
6 years ago

Nice, OpenCSV really work very well

milczarekIT
10 years ago

I also recommend opencsv library. It allow for mapping csv columns to class properties, (de)serializaion with this simple lib is pretty easy.

Bishop
1 year ago

Is it possible to display the file opened with openCSV in a JTable?

Grégor González
1 year ago

Oh nice one! OpenCSV do everything I need. Finally something that works with quotes and commas

Mohammad Tarique Khan
2 years ago

Thanks, really helpful.

Richard Lavallee
2 years ago

Is there a bug in your “Single class to read and parse a CSV file’ ?
I input a field of many double quotes, e.g. four in a row, or ten in a row and the output is always an empty field! I would have expected four to yield one. Or ten to yield four.

Please advise?

I am a great fan of yours in any case!

Richard Lavallee
2 years ago
Reply to  mkyong

yes — parses correctly. Can you provide a fix to your implementation which I prefer to use please?

Nico
3 years ago

Thanks MKYong ! Your knowledge is my cure. You are one of my hero’s. Your friend always, Nico. 👑💯

Marian
3 years ago

Very relevant examples!

Adam Erickson
4 years ago

I can’t even count the amount of times I have searched for solutions and cam to your page. Great job!
I’m looking for the same thing but with Tabs.

Hsiwei
6 years ago

Thanks.
It’s useful.

peter valencic
7 years ago

Thank you!

Sarah Ahmed
8 years ago

kindly i need to know how to read csv file from input stream

MKP
9 years ago

Thanks Mr.Mkyong, its highly helpful.

Anand Kadekar
10 years ago

HI mkyong,
This works pretty well with small files. But if file size is beyond 100MB this will probably not work.
I came across the situation where I need to compare two very large csv files. First I tried with java but then settled with Hadoop.

Girish Sharma
10 years ago

Good One You really Helps Me alot Keep sharing these kind of sample.

mahfuz
10 years ago

i have used opencsv. Opencsv can read the whole cav in memory to do a faster operation. Also writing csv is pretty easy using that, just google opencsv.
Happy Coding.