はじめに
事前に以下のライブラリを用意します。
- 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便利ツール@ツールタロウ