覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Gson - JsonWriterでインデント形式を変えてファイル出力してみる

以前JSON形式のデータをJavaで扱うためのGsonライブラリについて使い方を紹介しました。

今回はGsonライブラリのGsonオブジェクトを使わずにJSONファイルへの出力を行ってみます。
その際にインデントの形式をいくつか変えて出力します。

今回出力するJSONファイルの内容は以下のようなものとします

{
 "files": [
  {
   "name": "data-1.txt",
   "size": 1024,
   "type": "file",
   "update.time": 1538835662719
  },
  {
   "name": "data-2.txt",
   "size": 2048,
   "type": "file",
   "update.time": 1538835662719
  },
 ・・・繰り返し
 ]
}


インデントなしで出力

サンプルコードは以下の通りです。JsonWriter.setIndent メソッドを実行していないのが着目点になります。


■サンプルコード

import com.google.gson.stream.JsonWriter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class GsonTrial1 {

    public static void main(String[] args) throws Exception {
        write1(new File("sample1.json"));
    }

    private static void write1(File file) throws IOException {
        try (JsonWriter writer = new JsonWriter(new FileWriter(file))) {

            writer.beginObject();
            writer.name("files");
            writer.beginArray();

            for (int i = 1; i <= 10; i++) {
                writer.beginObject();
                writer.name("name").value("data-" + i + ".txt");
                writer.name("size").value(1024 * i);
                writer.name("type").value("file");
                writer.name("update.time").value(System.currentTimeMillis() + i);
                writer.endObject();
            }
            writer.endArray();
            writer.endObject();
        }
    }
}


■実行結果(ファイルへの出力内容)

{"files":[{"name":"data-1.txt","size":1024,"type":"file","update.time":1538835662718},{"name":"data-2.txt","size":2048,"type":"file","update.time":1538835662718},{"name":"data-3.txt","size":3072,"type":"file","update.time":1538835662718},{"name":"data-4.txt","size":4096,"type":"file","update.time":1538835662718},{"name":"data-5.txt","size":5120,"type":"file","update.time":1538835662718},{"name":"data-6.txt","size":6144,"type":"file","update.time":1538835662718},{"name":"data-7.txt","size":7168,"type":"file","update.time":1538835662718},{"name":"data-8.txt","size":8192,"type":"file","update.time":1538835662719},{"name":"data-9.txt","size":9216,"type":"file","update.time":1538835662719},{"name":"data-10.txt","size":10240,"type":"file","update.time":1538835662719}]}

JSONファイルとしての必要な形式は当然満たしていますが、人間が読むにはちょっと辛いかもしれません。


インデントありで出力

上記のサンプルでは出力されるJSONファイルの内容が人間にとって読みにくいので、今度は読みやすいようにインデントして出力してみます。


サンプルコードは以下の通りです。先ほどのサンプルとは異なりJsonWriter.setIndent メソッドを実行してインデントするようにしています。


■サンプルコード

import com.google.gson.stream.JsonWriter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class GsonTrial2 {

    public static void main(String[] args) throws Exception {
        write2(new File("sample2.json"));
    }

    private static void write2(File file) throws IOException {
        try (JsonWriter writer = new JsonWriter(new FileWriter(file))) {
            writer.setIndent(" ");  // インデントするようにした

            writer.beginObject();
            writer.name("files");
            writer.beginArray();

            for (int i = 1; i <= 10; i++) {
                writer.beginObject();
                writer.name("name").value("data-" + i + ".txt");
                writer.name("size").value(1024 * i);
                writer.name("type").value("file");
                writer.name("update.time").value(System.currentTimeMillis() + i);
                writer.endObject();
            }
            writer.endArray();
            writer.endObject();
        }
    }
}


■実行結果(ファイルへの出力内容)

{
 "files": [
  {
   "name": "data-1.txt",
   "size": 1024,
   "type": "file",
   "update.time": 1538836735394
  },
  {
   "name": "data-2.txt",
   "size": 2048,
   "type": "file",
   "update.time": 1538836735395
  },
  {
   "name": "data-3.txt",
   "size": 3072,
   "type": "file",
   "update.time": 1538836735397
  },
  {
   "name": "data-4.txt",
   "size": 4096,
   "type": "file",
   "update.time": 1538836735398
  },
  {
   "name": "data-5.txt",
   "size": 5120,
   "type": "file",
   "update.time": 1538836735399
  },
  {
   "name": "data-6.txt",
   "size": 6144,
   "type": "file",
   "update.time": 1538836735400
  },
  {
   "name": "data-7.txt",
   "size": 7168,
   "type": "file",
   "update.time": 1538836735401
  },
  {
   "name": "data-8.txt",
   "size": 8192,
   "type": "file",
   "update.time": 1538836735402
  },
  {
   "name": "data-9.txt",
   "size": 9216,
   "type": "file",
   "update.time": 1538836735404
  },
  {
   "name": "data-10.txt",
   "size": 10240,
   "type": "file",
   "update.time": 1538836735405
  }
 ]
}

JSONとしての内容に違いはありませんが、最初のサンプルに比べて人間が読みやすい形式になりました。


インデントありで出力(少しファイルサイズを気にする)

先ほどの実行サンプルで出力されるJSONファイルの内容は人間の目には見やすくなったのですが、
スペースや改行が入りまくるので、List内のデータ量が増えると出力したファイルサイズかなり大きくなってしまいます。

ファイルサイズをある程度抑えつつ、人間の目にも見やすい感じで出力してみます。


サンプルコードは以下の通りです。先ほどのサンプルとは異なりJsonWriter.setIndent メソッドを繰り返し処理の中で複数回実行してインデントをONにしたりOFFにしたりしています。


■サンプルコード

import com.google.gson.stream.JsonWriter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class GsonTrial2 {

    public static void main(String[] args) throws Exception {
        write3(new File("sample3.json"));
    }

    private static void write3(File file) throws IOException {
        try (JsonWriter writer = new JsonWriter(new FileWriter(file))) {
            writer.setIndent(" ");  // インデントON

            writer.beginObject();
            writer.name("files");
            writer.beginArray();

            for (int i = 1; i < 10; i++) {
                writer.beginObject();
                writer.setIndent("");    // インデントOFF
                writer.name("name").value("data-" + i + ".txt");
                writer.name("size").value(1024 * i);
                writer.name("type").value("file");
                writer.name("update.time").value(System.currentTimeMillis() + i);
                writer.endObject();
                writer.setIndent(" ");   // インデントON
            }
            writer.endArray();
            writer.endObject();
        }
    }


■実行結果(ファイルへの出力内容)

{
 "files": [
  {"name":"data-1.txt","size":1024,"type":"file","update.time":1538837153533},
  {"name":"data-2.txt","size":2048,"type":"file","update.time":1538837153534},
  {"name":"data-3.txt","size":3072,"type":"file","update.time":1538837153535},
  {"name":"data-4.txt","size":4096,"type":"file","update.time":1538837153536},
  {"name":"data-5.txt","size":5120,"type":"file","update.time":1538837153537},
  {"name":"data-6.txt","size":6144,"type":"file","update.time":1538837153538},
  {"name":"data-7.txt","size":7168,"type":"file","update.time":1538837153540},
  {"name":"data-8.txt","size":8192,"type":"file","update.time":1538837153541},
  {"name":"data-9.txt","size":9216,"type":"file","update.time":1538837153542}
 ]
}

人間が読みやすい形式を保ちつつ、ファイルサイズをある程度抑えた出力になりました、


まとめ

GsonJsonWriter.setIndentをうまく利用することで、出力するJSONののインデントをある程度制御することができました。



関連エントリ