تبدیل CSV به JSON
تبدیل CSV به JSON کار سادهای است. در این مطلب چند روش برای این کار را معرفی میکنیم.
اولین روش یک POJO(Plain-Old-Java-Object)i تعریف میکند و با شکستنهای ابتدایی رشته، داده CSV را به iPOJOتبدیل میکند که در ادامه به JSON سریالایز شود. روش دوم از یک پارسر کاملتر CSV با پشتیبانی از فیلدها و کاماها استفاده میکند. در این روش از کلاسهای Collection برای ذخیرهسازی داده پردازش شده و تبدیل آن به JSON استفاده میشود.
از Jackson برای تبدیل JSON استفاده میکنیم.
تجزیه فایل CSV ساده
در شرایطی که فایل CSV خیلی ساده باشد (هیچ فیلد نقل قول شده یا کاما درون فیلدها نداشته باشد) میتوان از یک الگوی ساده به شکل زیر استفاده کرد.
Pattern pattern = Pattern.compile(",");
تعریف POJO
public class Player { private int year; private String teamId; private String leagueId; private String playerId; private int salary; public Player(int year, String teamId, String leagueId, String playerId, int salary) { this.year = year; this.teamId = teamId; this.leagueId = leagueId; this.playerId = playerId; this.salary = salary; } // getters and setters here };
خواندن داده CSV
یک فایل CSV را با استفاده از BufferedReader در یک بلوک try-with-resource باز میکنیم.
try (BufferedReader in = new BufferedReader(new FileReader(csvFile));) { // processing code here }
لیستی از POJO به شکل زیر ایجاد میکنیم. اولین خط را به خاطر اینکه سرتیتر است رها میکنیم. هر خط با استفاده از Pattern به فیلدها شکسته میشود و به نوع داده مربوط تبدیل شده و برای ساخت اشیا استفاده میشود.
List<Player> players = in .lines() .skip(1) .map(line -> { String[] x = pattern.split(line); return new Player(Integer.parseInt(x[0]), x[1], x[2], x[3], Integer.parseInt(x[4])); }) .collect(Collectors.toList());
تبدیل کردن به JSON
زمانی که List آماده شد، از ObjectMapper جکسون برای نوشتن JSON استفاده میکنیم.
ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.writeValue(System.out, players);
و کل برنامه به این شکل خواهد بود
Pattern pattern = Pattern.compile(","); try (BufferedReader in = new BufferedReader(new FileReader(csvFile));) { List < Player > players = in .lines().skip(1).map(line - > { String[] x = pattern.split(line); return new Player(Integer.parseInt(x[0]), x[1], x[2], x[3], Integer.parseInt(x[4])); }).collect(Collectors.toList()); ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.writeValue(System.out, players); }
تبدیل CSV به JSON بدون POJO
در این مثال از پارسری که در اینجا معرفی شده استفاده میکنیم. این پارسر میتواند فیلدهای چندخطی و کامای درون فیلدها را هم پشتیبانی کند.
try (InputStream in = new FileInputStream(csvFile);) { CSV csv = new CSV(true, ',', in ); List < String > fieldNames = null; if (csv.hasNext()) fieldNames = new ArrayList < > (csv.next()); List < Map < String, String >> list = new ArrayList < > (); while (csv.hasNext()) { List < String > x = csv.next(); Map < String, String > obj = new LinkedHashMap < > (); for (int i = 0; i < fieldNames.size(); i++) { obj.put(fieldNames.get(i), x.get(i)); } list.add(obj); } ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.writeValue(System.out, list); }
به این ترتیب داده csv زیر را به عنوان ورودی داریم
rep_file_num,CIK,entity_name,street1,street2,city,state_code,zip,filing_date,doc_type_code 814-00034,0000731812,SIERRA RESOURCES CORP,629 J STREET,SUITE 202,SACRAMENTO,CA,95814,12/30/96,15 814-00053,0000821472,WESTFORD TECHNOLOGY VENTURES LP,17 ACADEMY ST 5TH FLOOR,[NULL],NEWARK,NJ,07102-2905,01/28/04,NO ACT ... 814-00098,0000878932,"EQUUS TOTAL RETURN, INC.",EIGHT GREENWAY PLAZA,SUITE 930,HOUSTON,TX,77046,08/25/16,40-
در خروجی این داده به فرمت json به شکل زیر درمیآید.
{ "rep_file_num" : "814-00098", "CIK" : "0000878932", "entity_name" : "EQUUS TOTAL RETURN, INC.", "street1" : "EIGHT GREENWAY PLAZA", "street2" : "SUITE 930", "city" : "HOUSTON", "state_code" : "TX", "zip" : "77046", "filing_date" : "08/25/16", "doc_type_code" : "40-APP/A" }
منبع: