简体   繁体   English

Java:CSV 文件易读/写

[英]Java: CSV File Easy Read/Write

I'm working on a program that requires quick access to a CSV comma-delimited spreadsheet file.我正在开发一个需要快速访问 CSV 逗号分隔电子表格文件的程序。 So far I've been able to read from it easily using a BufferedReader.到目前为止,我已经能够使用 BufferedReader 轻松读取它。 However, now I want to be able to edit the data it reads, then export it BACK to the CSV.但是,现在我希望能够编辑它读取的数据,然后将其导出回 CSV。

The spreadsheet contains names, phone numbers, email addresses, etc. And the program lists everyone's data, and when you click on them it brings up a page with more detailed information, also pulled from the CSV. On that page you can edit the data, and I want to be able to click a "Save Changes" button, then export the data back to its appropriate line in the CSV--or delete the old one, and append the new.电子表格包含姓名、电话号码、email 地址等。程序列出了每个人的数据,当你点击它们时,它会弹出一个页面,其中包含更详细的信息,也是从 CSV 中提取的。在该页面上,你可以编辑数据,我希望能够单击“保存更改”按钮,然后将数据导出回 CSV 中相应的行——或者删除旧的,append 新的。

I'm not very familiar with using a BufferedWriter, or whatever it is I should be using.我不太熟悉使用 BufferedWriter,或者我应该使用的任何东西。

What I started to do is create a custom class called FileIO.我开始做的是创建一个名为 FileIO 的自定义 class。 It contains both a BufferedReader and a BufferedWriter.它包含一个 BufferedReader 和一个 BufferedWriter。 So far it has a method that returns bufferedReader.readLine(), called read().到目前为止,它有一个返回 bufferedReader.readLine() 的方法,称为 read()。 Now I want a function called write(String line).现在我想要一个名为 write(String line) 的 function。

public static class FileIO {
    BufferedReader read;
    BufferedWriter write;

    public FileIO (String file) throws MalformedURLException, IOException {
        read = new BufferedReader(new InputStreamReader (getUrl(file).openStream()));
        write = new BufferedWriter (new FileWriter (file));
    }

    public static URL getUrl (String file) throws IOException {
        return //new URL (fileServer + file).openStream()));
                FileIO.class.getResource(file);
    }

    public String read () throws IOException {
        return read.readLine();
    }

    public void write (String line) {
        String [] data = line.split("\\|");
        String firstName = data[0];

        // int lineNum = findLineThatStartsWith(firstName);
        // write.writeLine(lineNum, line);
    }
};

I'm hoping somebody has an idea as to how I can do this?我希望有人知道我该怎么做?

Rather than reinventing the wheel you could have a look at OpenCSV which supports reading and writing of CSV files.您可以查看支持读取和写入 CSV 文件的OpenCSV ,而不是重新发明轮子。 Here are examples of reading & writing以下是阅读和写作的例子

Please consider Apache commons csv .请考虑Apache commons csv To fast understand the api, there are four important classes:为了快速理解api,有四个重要的类:

CSVFormat CSV格式

Specifies the format of a CSV file and parses input.指定 CSV 文件的格式并解析输入。

CSVParser CSV解析器

Parses CSV files according to the specified format.根据指定的格式解析 CSV 文件。

CSVPrinter CSV打印机

Prints values in a CSV format.以 CSV 格式打印值。

CSVRecord CSV记录

A CSV record parsed from a CSV file.从 CSV 文件解析的 CSV 记录。

Code Example:代码示例: 在此处输入图片说明

Unit test code:单元测试代码: 在此处输入图片说明

The spreadsheet contains names, phone numbers, email addresses, etc. And the program lists everyone's data, and when you click on them it brings up a page with more detailed information, also pulled from the CSV.电子表格包含姓名、电话号码、电子邮件地址等。该程序列出了每个人的数据,当您单击它们时,它会显示一个包含更详细信息的页面,这些信息也是从 CSV 中提取的。 On that page you can edit the data, and I want to be able to click a "Save Changes" button, then export the data back to its appropriate line in the CSV--or delete the old one, and append the new.在该页面上,您可以编辑数据,我希望能够单击“保存更改”按钮,然后将数据导出回 CSV 中的相应行——或者删除旧的,并附加新的。

The content of a file is a sequence of bytes.文件的内容是一个字节序列。 CSV is a text based file format, ie the sequence of byte is interpreted as a sequence of characters, where newlines are delimited by special newline characters. CSV 是一种基于文本的文件格式,即将字节序列解释为字符序列,其中换行符由特殊的换行符分隔。

Consequently, if the length of a line increases, the characters of all following lines need to be moved to make room for the new characters.因此,如果一行的长度增加,则需要移动所有后续行的字符以为新字符腾出空间。 Likewise, to delete a line you must move the later characters to fill the gap.同样,要删除一行,您必须移动后面的字符以填补空白。 That is, you can not update a line in a csv (at least not when changing its length) without rewriting all following lines in the file.也就是说,如果不重写文件中的所有后续行,就不能更新 csv 中的一行(至少在更改其长度时不能)。 For simplicity, I'd rewrite the entire file.为简单起见,我会重写整个文件。

Since you already have code to write and read the CSV file, adapting it should be straightforward.由于您已经拥有编写和读取 CSV 文件的代码,因此修改它应该很简单。 But before you do that, it might be worth asking yourself if you're using the right tool for the job.但在此之前,不妨问问自己是否使用了适合这项工作的工具。 If the goal is to keep a list of records, and edit individual records in a form, programs such as Microsoft Access or whatever the Open Office equivalent is called might be a more natural fit.如果目标是保留记录列表,并在表单中编辑单个记录,则 Microsoft Access 或 Open Office 等价物之类的程序可能更适合。 If you UI needs go beyond what these programs provide, using a relational database to keep your data is probably a better fit (more efficient and flexible than a CSV).如果您的 UI 需要超出这些程序提供的范围,那么使用关系数据库来保存您的数据可能更合适(比 CSV 更有效和灵活)。

Add Dependencies添加依赖项

implementation 'com.opencsv:opencsv:4.6'

Add Below Code in onCreate()在 onCreate() 中添加以下代码

InputStreamReader is = null;
        try {
              String path= "storage/emulated/0/Android/media/in.bioenabletech.imageProcessing/MLkit/countries_image_crop.csv";
            
             CSVReader reader = new CSVReader(new FileReader(path));
             String[] nextLine;
             int lineNumber = 0;
             while ((nextLine = reader.readNext()) != null) {
                lineNumber++;

                //print CSV file according to your column 1 means first column, 2 means 
                  second column
                Log.e(TAG, "onCreate: "+nextLine[2] );
            }
        }
        catch (Exception e)
        {
             Log.e(TAG, "onCreate: "+e );
        }

I solved it using我解决了它使用

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-csv</artifactId>
        <version>2.8.6</version>
    </dependency>

and

  private static final CsvMapper mapper = new CsvMapper();
  public static <T> List<T> readCsvFile(MultipartFile file, Class<T> clazz) throws IOException {
    InputStream inputStream = file.getInputStream();
    CsvSchema schema = mapper.schemaFor(clazz).withHeader().withColumnReordering(true);
    ObjectReader reader = mapper.readerFor(clazz).with(schema);
    return reader.<T>readValues(inputStream).readAll();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM