简体   繁体   English

如何在 Java 中读取多行值 CSV 文件?

[英]How to read multiple line value CSV files in Java?

Since a valid JSON file may contain only one JSON I intend to put multiple JSONs into a CSV file separated by a ";"由于一个有效的 JSON 文件可能只包含一个 JSON,我打算将多个 JSON 放入一个以“;”分隔的 CSV 文件中。 and to read it using OpenCSV.并使用 OpenCSV 读取它。 (It's for putting those JSON data in file apart from the JUnit class to make it better readable.) (这是为了将那些 JSON 数据放在文件中,而不是 JUnit 类,以使其更具可读性。)

Is there a way to read multiple lines until the delimiter ";"有没有办法读取行直到分隔符“;” occurs?发生? Maybe it would be a good idea to enhance the JSON by an additional field _name which could be used as a key for a Map to read the JSON into!??也许通过附加字段_name增强 JSON 是一个好主意,该字段可以用作 Map 将 JSON 读入的键!?? I tried it this way first to read into a List but it reads all lines into the list just eliminating the ";".我首先尝试以这种方式读入列表,但它将所有行读入列表,只是消除了“;”。 I need a way to read until ";"我需要一种阅读方式,直到“;” occurs, store all lines read before into the Map<String, String> or better Map<String, JsonNode> and continue with the next.发生时,将之前读取的所有行存储到 Map<String, String> 或更好的 Map<String, JsonNode> 中,然后继续下一个。

    final ClassLoader classLoader = CrmServiceUT.class.getClassLoader();
    final File file = new File(classLoader.getResource("data/UpdatedDeal1.csv").getFile());
    final List<List<String>> records = new ArrayList<List<String>>();
    final CSVParser parser = new CSVParserBuilder().withSeparator(';').build();
    try (final BufferedReader br = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8);
         final CSVReader csvReader = new CSVReaderBuilder(br).withCSVParser(parser).build()){
        String[] values = null;
                List<String> list = null;
        while ((values = csvReader.readNext()) != null) {
            if( !Stream.of(values).anyMatch(x -> x.contains(";")) ) {
                list = Arrays.asList(values);
            }
            if(list.contains(";")) {
                list.remove(";");
            }
                records.add(list);
        }
    } catch (CsvValidationException e) {
        e.printStackTrace();
    } catch (CsvException e) {
        e.printStackTrace();
    }

The JSON may be totally different with a few or a lot of lines: JSON 可能完全不同,有几行或很多行:

{
  "_nodeName": "updatedDeal1",
  "results": [
    184896670
  ],
  "hasMore": false,
  "offset": 184896670
}
;
{
"_nodeName": "updatedDeal1",
"results": [
184896670
],
"hasMore": false,
"abcde": "xyz",
"offset": 184896670
}

With LHCHIN's answer I ended up in this solution to additionally handle the case that the delimiter (';') may be followed by the next JSON in one line:有了 LHCHIN 的回答,我最终在这个解决方案中额外处理了分隔符 (';') 可能跟在一行中的下一个 JSON 的情况:

@BeforeAll
public static void beforeAll() throws IOException {
    final ClassLoader classLoader = CrmServiceUT.class.getClassLoader();
    final File file = new File(classLoader.getResource("data/jsonsUT.csv").getFile());
    final StringBuilder sb = new StringBuilder();
    for (final String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) {
        sb.append(line);
        if (line.endsWith(";")) {
            putJsonToMap(sb.substring(0, sb.length()-1));
            sb.delete(0, sb.length());
        }
    }
    putJsonToMap(sb.substring(0, sb.length()));
}

/**
 * Fills a map with JSON used throughout the unit tests.
 *
 * @param jsonStr       The JSON to be stored.
 * @throws IOException
 */
private static void putJsonToMap(final String jsonStr) throws IOException {
    final JsonNode node = mapper.readTree(jsonStr);
    jsons.put(node.get("_nodeName").asText(), node);
    ((ObjectNode) node).remove("_nodeName");
}

For your case, I cannot see any advantage to use opencsv , so why not just handle it by yourself!对于您的情况,我看不到使用opencsv任何优势,那么为什么不自己处理呢!

Following example shows how to read a given CSV file line by line and put each line into a StringBuilder for concatenation, then once you find a line which ends with ;以下示例显示了如何逐行读取给定的 CSV 文件并将每一行放入StringBuilder进行连接,然后一旦找到以;结尾的行; , add the content of StringBuilder to a list of String . ,将StringBuilder的内容添加到String的列表中。

Code snippet代码片段

List<String> records = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (String line : Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)) {
    sb.append(line);
    if (line.endsWith(";")) {
        records.add(sb.substring(0, sb.length()-1));
        sb.delete(0, sb.length());
    }
}

After that, each element in the List is a JSON string, you can access them directly for further manipulation.之后, List中的每个元素都是一个 JSON 字符串,您可以直接访问它们以进行进一步操作。

You can read CSV file just like this and can get each row and column您可以像这样读取 CSV 文件,并可以获取每一行和每一列

BufferedReader csvReader;
csvReader = new BufferedReader(new FileReader(file.getPath())); // csv file path
while ((row = csvReader.readLine()) != null) {
String[] data = row.split(",");  // in data you have each column value for each row
}

我想,就去做吧。

json.replace('\n', '').replace(';','\n');

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

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