Skip to content

bytefish/JTinyCsvParser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 

Repository files navigation

JTinyCsvParser

JTinyCsvParser is a high-performance CSV Parser for Java 1.8. As the name implies it is a Java version of TinyCsvParser.

It makes no use of Reflection and is very easy to use and extend.

Setup

JTinyCsvParser is available in the Central Maven Repository.

You can add the following dependencies to your pom.xml to include JTinyCsvParser in your project.

<dependency>
	<groupId>de.bytefish</groupId>
	<artifactId>jtinycsvparser</artifactId>
	<version>1.2</version>
</dependency>

Documentation

JTinyCsvParser comes with a documentation, which is located at:

Quickstart

This is only an example for the most common use of JTinyCsvParser. For more detailed information on custom formats and more advanced use-cases, please consult the full User Guide of the official documentation.

Imagine we have list of persons in a CSV file persons.csv with their first name, last name and birthdate. The columns are separated by , as column delimiter, which each line will be split at:

Philipp;Wagner;1986/05/12
Max;Musterman;2014/01/02

The corresponding domain model in our Java code might look like this.

public class Person {

	private String firstName;
	private String lastName;
	private LocalDate BirthDate;

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public LocalDate getBirthDate() {
		return BirthDate;
	}

	public void setBirthDate(LocalDate birthDate) {
		BirthDate = birthDate;
	}
}

When using JTinyCsvParser you have to define the mapping between the columns in the CSV data and the property in you domain model, which is done by implementing the class CsvMapping<TEntity>, where TEntity is the class Person.

The IObjectCreator passed into the mapping is a functional interface, which returns a TEntity object. It is used to instantiate instances of the target objects, without using the Java Reflection API in the library.

public class PersonMapping extends CsvMapping<Person> {

    public PersonMapping(IObjectCreator creator) {
        super(creator);

        mapProperty(0, String.class, Person::setFirstName);
        mapProperty(1, String.class, Person::setLastName);
        mapProperty(2, LocalDate.class, Person::setBirthDate);
    }
}

The method mapProperty is used to map between the column number in the CSV file and the property in the domain model.

Then we can use the mapping to parse the CSV data with a CsvParser. In the CsvParserOptions we are defining to not skip the header and use a , as column delimiter. I have assumed, that the file is encoded as UTF8.

public class CsvParserTest {

    @Test
    public void testParse_readFromFile() {
        
		// Use , as column delimiter and do not skip the header:
        CsvParserOptions options = new CsvParserOptions(false, ",");
        
		// Create the Mapping:
        PersonMapping mapping = new PersonMapping(() -> new Person());
        
		// Create the Parser:
        CsvParser<Person> parser = new CsvParser<>(options, mapping);
        
		// Path to read from:
        Path csvFile = FileSystems.getDefault().getPath("C:\\csv", "persons.txt");
        
		// Holds the Results:
        List<CsvMappingResult<Person>> result;
        
		// Read the CSV File:
        try (Stream<CsvMappingResult<Person>> stream = parser.readFromFile(csvFile, StandardCharsets.UTF_8)) {
            result = stream.collect(Collectors.toList()); // turn it into a List!
        }
		
        // Do we have a result?
        Assert.assertNotNull(result);
    
        // Do we have two persons?
        Assert.assertEquals(2, result.size());
    
        // Get the first person:
        Person person0 = result.get(0).getResult();
    
        Assert.assertEquals("Philipp", person0.firstName);
        Assert.assertEquals("Wagner", person0.lastName);
        Assert.assertEquals(1986, person0.getBirthDate().getYear());
        Assert.assertEquals(5, person0.getBirthDate().getMonthValue());
        Assert.assertEquals(12, person0.getBirthDate().getDayOfMonth());
    
        // Get the second person:
        Person person1 = result.get(1).getResult();
    
        Assert.assertEquals("Max", person1.firstName);
        Assert.assertEquals("Musterman", person1.lastName);
        Assert.assertEquals(2000, person1.getBirthDate().getYear());
        Assert.assertEquals(1, person1.getBirthDate().getMonthValue());
        Assert.assertEquals(7, person1.getBirthDate().getDayOfMonth());
    }
	
}

Reading From a String

Reading from a string is possible with the :code:CsvParser.readFromString method.

public class CsvParserTest {

    @Test
    public void testParse_ReadFromString() throws Exception {
        
		// Use , as column delimiter and do not skip the header:
        CsvParserOptions options = new CsvParserOptions(false, ",");
		
		// Create the Mapping:
        PersonMapping mapping = new PersonMapping(() -> new Person());
        
		// Create the Parser:
        CsvParser<Person> parser = new CsvParser<>(options, mapping);
        
		// Define the Line Separator:
        String lineSeparator = System.getProperty("line.separator");
        
		// Create some CSV Data:
        String csvData = "Philipp,Wagner,1986-05-12" + lineSeparator + "Max,Musterman,2000-01-07";
        
		// Parse the CSV Data String:
        List<CsvMappingResult<Person>> result =  parser.readFromString(csvData, new CsvReaderOptions(lineSeparator))
                .collect(Collectors.toList()); // turn it into a List!
				
        // Do we have results?
        Assert.assertNotNull(result);

		// Do we have two persons?
        Assert.assertEquals(2, result.size());

        // Get the first person:
        Person person0 = result.get(0).getResult();

        Assert.assertEquals("Philipp", person0.firstName);
        Assert.assertEquals("Wagner", person0.lastName);
        Assert.assertEquals(1986, person0.getBirthDate().getYear());
        Assert.assertEquals(5, person0.getBirthDate().getMonthValue());
        Assert.assertEquals(12, person0.getBirthDate().getDayOfMonth());

        // Get the second person:
        Person person1 = result.get(1).getResult();

        Assert.assertEquals("Max", person1.firstName);
        Assert.assertEquals("Musterman", person1.lastName);
        Assert.assertEquals(2000, person1.getBirthDate().getYear());
        Assert.assertEquals(1, person1.getBirthDate().getMonthValue());
        Assert.assertEquals(7, person1.getBirthDate().getDayOfMonth());
    }
	
}    

About

Easy to use, easy to extend and high-performance library for CSV parsing with Java

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published