はじめに
事前に以下のライブラリを用意します。
- iCal4j
- jarファイルをMaven Repositoryから取得すると使いやすいです。
- http://mvnrepository.com/artifact/org.mnode.ical4j/ical4j/1.0.7
- ※”Download ( JAR ) “のリンクからダウンロード
iCalendar形式は、1行75octet以内とし、文字列が2行目以降に続く場合には2行目以降の行頭に空白が入ります。
iCal4jを普通に使うと2行目以降の空白でパースエラーになったため、icsファイルの内容を事前に整形しています(当方がiCal4jの実装を見落としている可能性があり、もっとよい方法があるかもしれません)。
パースするiCalendarは以下のファイルを使います。
input.ics
BEGIN:VCALENDAR VERSION:2.0 PRODID:-//tool-taro//iCal 2.0//EN BEGIN:VEVENT UID:taro@tool-taro.com DTSTART;VALUE=DATE:20160204 DTEND;VALUE=DATE:20160204 SUMMARY:三色団子1本目食べる DESCRIPTION:あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 END:VEVENT BEGIN:VEVENT UID:taro@tool-taro.com DTSTART;VALUE=DATE:20160205 DTEND;VALUE=DATE:20160205 SUMMARY:三色団子2本目食べる DESCRIPTION:あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 END:VEVENT BEGIN:VEVENT UID:taro@tool-taro.com DTSTART;VALUE=DATE:20160206 DTEND;VALUE=DATE:20160206 SUMMARY:三色団子3本目食べる DESCRIPTION:あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 END:VEVENT BEGIN:VEVENT UID:taro@tool-taro.com DTSTART;VALUE=DATE:20160207 DTEND;VALUE=DATE:20160207 SUMMARY:三色団子補充 DESCRIPTION:あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 END:VEVENT END:VCALENDAR
実装例
サンプルでは、動作確認しやすいようにmainメソッドで実行できるようにしてあります。
ICalParser.java
import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Iterator; import net.fortuna.ical4j.data.CalendarBuilder; import net.fortuna.ical4j.data.ParserException; import net.fortuna.ical4j.model.Calendar; import net.fortuna.ical4j.model.Component; import net.fortuna.ical4j.model.Property; /** * * @author tool-taro.com */ public class ICalParser { public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException, ParserException { //パースしたいicsファイルの保存場所 String inputFilePath = "input.ics"; //icsファイルのエンコーディング String encoding = "UTF-8"; //パース処理 //iCal4jの2行目以降の実装が充分でない処理を補助 StringBuilder icalBuilder = new StringBuilder(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFilePath), encoding)); String line; while (true) { line = reader.readLine(); if (line == null) { break; } if (!line.startsWith(" ") && icalBuilder.length() > 0) { icalBuilder.append("\n"); } icalBuilder.append(line); } reader.close(); CalendarBuilder builder = new CalendarBuilder(); Calendar calendar = builder.build(new ByteArrayInputStream(icalBuilder.toString().getBytes(encoding))); Component component; Property property; for (Iterator i = calendar.getComponents().iterator(); i.hasNext();) { component = (Component) i.next(); System.out.format("Component=%1$s\n", component.getName()); for (Iterator j = component.getProperties().iterator(); j.hasNext();) { property = (Property) j.next(); System.out.format("Property=%1$s, %2$s\n", property.getName(), property.getValue()); } } } finally { if (reader != null) { try { reader.close(); } catch (Exception e) { } } } } }
動作確認
$ javac ICalParser.java $ java ICalParser $ Component=VEVENT Property=UID, taro@tool-taro.com Property=DTSTART, 20160204 Property=DTEND, 20160204 Property=SUMMARY, 三色団子1本目食べる Property=DESCRIPTION, あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 Component=VEVENT Property=UID, taro@tool-taro.com Property=DTSTART, 20160205 Property=DTEND, 20160205 Property=SUMMARY, 三色団子2本目食べる Property=DESCRIPTION, あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 Component=VEVENT Property=UID, taro@tool-taro.com Property=DTSTART, 20160206 Property=DTEND, 20160206 Property=SUMMARY, 三色団子3本目食べる Property=DESCRIPTION, あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。 Component=VEVENT Property=UID, taro@tool-taro.com Property=DTSTART, 20160207 Property=DTEND, 20160207 Property=SUMMARY, 三色団子補充 Property=DESCRIPTION, あああ..こんな風に2行以上にわたる場合には2行目以降の行頭に 空白が入っています。
環境
- 開発
- Windows 10 Pro
- JDK 1.8.0_74
- NetBeans IDE 8.1
- 動作検証
- CentOS Linux release 7.2
- JDK 1.8.0_74
Webツールも公開しています。
Web便利ツール@ツールタロウ