Since a valid JSON file may contain only one JSON I intend to put multiple JSONs into a CSV file separated by a ";" and to read it using OpenCSV. (It's for putting those JSON data in file apart from the JUnit class to make it better readable.)
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!?? 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.
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:
{
"_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:
@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!
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 ;
, add the content of StringBuilder
to a list of 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.
You can read CSV file just like this and can get each row and column
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');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.