{"id":21384077,"url":"https://github.com/nbbrd/picocsv","last_synced_at":"2025-07-13T14:31:32.627Z","repository":{"id":37934731,"uuid":"207502578","full_name":"nbbrd/picocsv","owner":"nbbrd","description":"Unusual CSV library for Java","archived":false,"fork":false,"pushed_at":"2025-07-05T15:00:19.000Z","size":2005,"stargazers_count":7,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-07-05T16:20:39.422Z","etag":null,"topics":["csv","java","jpms","library","single-file-source-code","zero-dependency"],"latest_commit_sha":null,"homepage":"https://nbbrd.github.io/picocsv/docs/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nbbrd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-09-10T08:16:29.000Z","updated_at":"2025-07-05T15:00:16.000Z","dependencies_parsed_at":"2023-02-18T03:01:37.196Z","dependency_job_id":"8b586d1c-0b33-4214-8799-d609071fe9a0","html_url":"https://github.com/nbbrd/picocsv","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/nbbrd/picocsv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbbrd%2Fpicocsv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbbrd%2Fpicocsv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbbrd%2Fpicocsv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbbrd%2Fpicocsv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nbbrd","download_url":"https://codeload.github.com/nbbrd/picocsv/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nbbrd%2Fpicocsv/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265155702,"owners_count":23719566,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","java","jpms","library","single-file-source-code","zero-dependency"],"created_at":"2024-11-22T11:37:56.952Z","updated_at":"2025-07-13T14:31:32.615Z","avatar_url":"https://github.com/nbbrd.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# picocsv - unusual CSV library for Java\n\n[![Download](https://img.shields.io/github/release/nbbrd/picocsv.svg)](https://github.com/nbbrd/picocsv/releases/latest)\n[![Changes](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fnbbrd%2Fpicocsv%2Fbadges%2Funreleased-changes.json)](https://github.com/nbbrd/picocsv/blob/develop/CHANGELOG.md)\n[![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/com/github/nbbrd/picocsv/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/com/github/nbbrd/picocsv/README.md)\n\n**Picocsv is an unusual CSV library designed to be embedded in other libraries.**  \nWhile it can be used directly, it's main purpose is to be the core foundation of those other libraries.  \nFor a more user-friendly CSV library, you should have a look at the fast and well-documented [FastCSV library](https://github.com/osiegmar/FastCSV/).\n\n👍 Key points:\n\n- lightweight library with no dependency (~25KB)\n- very fast (cf. [benchmark](https://github.com/osiegmar/JavaCsvBenchmarkSuite)) and efficient (no heap memory allocation)\n- designed to be embedded into other libraries\n  as [an external dependency](https://search.maven.org/artifact/com.github.nbbrd.picocsv/picocsv)\n  or [as a single-file source](https://github.com/nbbrd/picocsv/blob/develop/src/main/java/nbbrd/picocsv/Csv.java)\n- has a module-info that makes it compatible with [JPMS](https://www.baeldung.com/java-9-modularity)\n- compatible with GraalVM Native Image (genuine Java, no reflection, no bytecode manipulation)\n- can be easily shaded\n- Java 8 minimum requirement\n\n🚀 Features:\n\n- [reads/writes](#readwrite) CSV from/to character streams\n- provides a minimalist [null-free](#null-free-api) low-level API\n- does not interpret content\n- does not correct invalid files\n- follows the [RFC4180](https://tools.ietf.org/html/rfc4180) specification\n- supports [custom line separator, field delimiter, quoting character and comment character](#custom-formats)\n- supports custom quoting strategy\n- supports unicode characters\n\n\u003e [!IMPORTANT]\n\u003e Note that the `Csv.Format#acceptMissingField` option must be set to `false` to closely follow the RFC4180 specification.\n\u003e The default value is currently `true` but will be reversed in the next major release.\n\n## Features\n\n### Read/Write\n\npicocsv provides a low-level API to read and write CSV files from/to character streams.  \nThis API follows the [try-with-resources statement](https://www.baeldung.com/java-try-with-resources)\nand closes the underlying character stream after use.\n\n#### Reading character streams\n\nThe reading is done by the `Csv.Reader` class and has the following characteristics:\n\n- it is instantiated by the `Csv.Reader.of(Csv.Format, Csv.ReaderOptions, java.io.Reader)` factory method\n- its options are defined by the `Csv.ReaderOptions` class\n\nTypical reader instantiation and usage:\n\n```java\ntry (java.io.Reader chars = ...) {\n  try (Csv.Reader reader = Csv.Reader.of(Csv.Format.DEFAULT, Csv.ReaderOptions.DEFAULT, chars)) {\n    ...\n  }\n}\n```\n\nBasic reading 1️⃣ of all fields 2️⃣ skipping comments 3️⃣:\n\n```java\nwhile (reader.readLine()) {      // 1️⃣\n  if (!reader.isComment()) {     // 3️⃣\n    while (reader.readField()) { // 2️⃣\n      CharSequence field = reader;\n      ...\n    }\n  }\n}\n```\n\nConfiguring reading options:\n\n```java\nCsv.ReaderOptions strict = Csv.ReaderOptions.builder().lenientSeparator(false).build();\n```\n\n#### Writing character streams\n\nThe writing is done by the `Csv.Writer` class and has the following characteristics:\n\n- it is instantiated by the `Csv.Writer.of(Csv.Format, Csv.WriterOptions, java.io.Writer)` factory method\n- its options are defined by the `Csv.WriterOptions` class\n\nTypical writer instantiation and usage:\n\n```java\ntry (java.io.Writer chars = ...) {\n  try (Csv.Writer writer = Csv.Writer.of(Csv.Format.DEFAULT, Csv.WriterOptions.DEFAULT, chars)) {\n    ...\n  }\n}\n```\n\nBasic writing 1️⃣ of some fields 2️⃣ and comments 3️⃣:\n\n```java\nwriter.writeComment(\"Some comment\"); // 3️⃣\nwriter.writeField(\"Some field\");     // 2️⃣\nwriter.writeEndOfLine();             // 1️⃣\n```\n\nConfiguring writing options:\n\n```java\nCsv.WriterOptions customOptions = Csv.WriterOptions.builder().maxCharsPerField(1024).build();\n```\n\n### Null-free API\n\npicocsv provides a null-free API that accepts null parameters and returns non-null values.\n\n```java\nwriter.writeComment(null); // same as `csv.writeComment(\"\")`\nwriter.writeField(null); // same as `csv.writeField(\"\")`\n```\n\n### Custom formats\n\nCustom formats are defined by the `Csv.Format` object:\n\n| Option       | Description       | Default Value |\n|--------------|-------------------|---------------|\n| `#separator` | Line separator    | `\\r\\n`        |\n| `#delimiter` | Field delimiter   | `,`           |\n| `#quote`     | Quoting character | `\"`           |\n| `#comment`   | Comment character | `#`           |\n\n```java\nCsv.Format tsv = Csv.Format.builder().delimiter('\\t').build();\nCsv.Format embedded = Csv.Format.builder().delimiter('=').separator(\",\").build();\n```\n\n## Cookbook\n\n### Readable/Appendable\n\npicocsv only supports `java.io.Reader`/`java.io.Writer` as input/output for performance reasons.\nHowever, it is still possible to use `Readable`/`Appendable` by wrapping them in adapters.\n\nSee [`Cookbook#asCharReader(Readable)`](https://github.com/nbbrd/picocsv/blob/develop/src/test/java/_demo/Cookbook.java) and [`Cookbook#asCharWriter(Appendable)`](https://github.com/nbbrd/picocsv/blob/develop/src/test/java/_demo/Cookbook.java).\n\n### Disabling comments\n\nComments can be disabled by setting the `Csv.Format#comment` option to the null character `\\0`.\n\n```java\nCsv.Format noComment = Csv.Format.builder().comment('\\0').build();\n```\n\n\u003e [!NOTE]\n\u003e Note that this might lead to problems since binary data is allowed in [RFC-4180-bis](https://fastcsv.org/architecture/interpretation/#status-of-the-rfc).\n\u003e It will be fixed in a future release.\n\n### Skipping comments\n\nComments can be skipped by using the `Csv.Reader#isComment()` method.\n\n```java\nwhile (reader.readLine()) {\n    if (!reader.isComment()) {\n        while (reader.readField()) { ... }\n    }\n}\n```\n\nSee [`Cookbook#skipComments(Csv.Reader)`](https://github.com/nbbrd/picocsv/blob/develop/src/test/java/_demo/Cookbook.java).\n\n### Skipping empty lines\n\nEmpty lines are valid lines represented by a single empty field in RFC-4180.  \nHowever, it is still possible to skip them by using the `Csv.Format#acceptMissingField` option.\n\n```java\nCsv.Format format = Csv.Format.builder().acceptMissingField(true).build();\ntry (Csv.Reader reader = ...) {\n    while (reader.readLine()) {\n        if (!reader.readField()) {\n            continue; // 💡 line without field =\u003e empty line\n        }\n        do { ... } while (reader.readField());\n    }\n}\n```\n\n### Skipping fields\n\nFields can be skipped by reading them without using their value. \nThe underlying implementation does not allocate heap memory to parse fields \nand provides access to those fields through a `CharSequence` interface.\nTherefore, the string value creation is delayed until it is actually needed, reducing memory usage and garbage collection.\n\n```java\ntry (Csv.Reader reader = ...) {\n    while (reader.readLine()) {\n        reader.readField(); // 💡 read field but do not use it =\u003e skip it\n        while (!reader.readField()) {\n          String field = reader.toString(); // use the field value\n        }\n    }\n}\n```\n\nSee [`Cookbook#skipFields(Csv.Reader, int)`](https://github.com/nbbrd/picocsv/blob/develop/src/test/java/_demo/Cookbook.java).\n\n## Setup\n\nMaven setup:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.nbbrd.picocsv\u003c/groupId\u003e\n    \u003cartifactId\u003epicocsv\u003c/artifactId\u003e\n    \u003cversion\u003eLATEST_VERSION\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Developing\n\nThis project is written in Java and uses [Apache Maven](https://maven.apache.org/) as a build tool.  \nIt requires [Java 8 as minimum version](https://whichjdk.com/) and all its dependencies are hosted on [Maven Central](https://search.maven.org/).\n\nThe code can be build using any IDE or by just type-in the following commands in a terminal:\n\n```shell\ngit clone https://github.com/nbbrd/picocsv.git\ncd picocsv\nmvn clean install\n```\n\n## Contributing\n\nAny contribution is welcome and should be done through pull requests and/or issues.\n\n## Licensing\n\nThe code of this project is licensed under the [European Union Public Licence (EUPL)](https://joinup.ec.europa.eu/page/eupl-text-11-12).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnbbrd%2Fpicocsv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnbbrd%2Fpicocsv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnbbrd%2Fpicocsv/lists"}