How do I write to a YAML file using SnakeYaml?

35,011

Solution 1

If I've understood the question, it doesn't seem to have anything to do with YAML or SnakeYAML per se, but to do with how you write to a specific file in Java. Basically, what the second example you copied is showing is how to dump an object to an arbitrary java.io.Writer object (though they use a StringWriter as this will not write anything to disk). If you want to modify this example to write to a particular file, you can do so by making use of a FileWriter, like so:

public void testDumpWriter() {
   Map<String, Object> data = new HashMap<String, Object>();
   data.put("name", "Silenthand Olleander");
   data.put("race", "Human");
   data.put("traits", new String[] { "ONE_HAND", "ONE_EYE" });

   Yaml yaml = new Yaml();
   FileWriter writer = new FileWriter("/path/to/file.yaml");
   yaml.dump(data, writer);
}

Which will dump the map data to a YAML file. Note that it is not normally necessary to create the file yourself before opening the FileWriter as the FileWriter will handle that for you.

Solution 2

To pretty print in expected yaml format (without the braces, like in accepted answer):

public static void saveYamlToFile(final Object object) throws IOException {
    final DumperOptions options = new DumperOptions();
    options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
    options.setPrettyFlow(true);
    final Yaml yaml = new Yaml(options);

    final FileWriter writer = new FileWriter("/path/to/file.yaml");
    yaml.dump(object, writer);
}

Solution 3

Else one way to write data

 Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");

        YamlWriter writer = new YamlWriter(new FileWriter("test.yml"));
        writer.write(map);
        writer.close();

Output:

  key1: value1
  key2: value2
  key3: value3

For me, in this case, I see a more readable output. From the first solution, we will see output like this:

{key1: value1, key2: value2, key3: value3}

If we will have a lot of data it will be hard to read

P.S. we need some dependency

    <dependency>
        <groupId>com.esotericsoftware.yamlbeans</groupId>
        <artifactId>yamlbeans</artifactId>
        <version>1.13</version>
    </dependency>
Share:
35,011
Jonas Bartkowski
Author by

Jonas Bartkowski

Updated on June 11, 2020

Comments

  • Jonas Bartkowski
    Jonas Bartkowski almost 4 years

    Consider the following code:

    public static void dumpObjectToYaml(String key, Object O, String path) throws IOException
    {
        Map<String, Object> data = new HashMap<>();
        data.put(key, O);
    
        File F = new File(path);
        F.mkdirs();
        F.createNewFile();
    
        //write data to File
    }
    

    This method is aiming to write the given Object O at the given key, into the YAML file at the given path. (if it doesn't exist it is created.) But obviously the main part is still missing.

    Now following the documentation of SnakeYaml, to create a YAML I only need to create a map and put in the Objects at the right keys, which I did.

    But nowhere (at least I don't see it) is described how to create a yaml file at a certain path!

    The only thing I found was:

    "The Yaml.dump(Object data) method accepts a Java object and produces a YAML document"

    public void testDump() 
    {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("name", "Silenthand Olleander");
        data.put("race", "Human");
        data.put("traits", new String[] { "ONE_HAND", "ONE_EYE" });
        Yaml yaml = new Yaml();
        String output = yaml.dump(data);
        System.out.println(output);
    }
    

    and

    "Yaml.dump(Object data, Writer output) will write the produced YAML document into the specified file/stream."

    public void testDumpWriter() 
    {
       Map<String, Object> data = new HashMap<String, Object>();
       data.put("name", "Silenthand Olleander");
       data.put("race", "Human");
       data.put("traits", new String[] { "ONE_HAND", "ONE_EYE" });
       Yaml yaml = new Yaml();
       StringWriter writer = new StringWriter();
       yaml.dump(data, writer);
       System.out.println(writer.toString());
    }
    

    But still, even though it says exactly that at the second bit of code, it doesn't seem to support the manipulation of a certain file and it's certainly not shown how to do it.

    Is it only me or does the documentation feel very cryptic and specified? Half of it is about special applications that I have never even heard about. I feel really dumb just by looking at it and it makes me kind of angry.

    Anyhow; I would really appreciate any help that you could give me.

  • Jonas Bartkowski
    Jonas Bartkowski almost 10 years
    Thank you (: That was exactly what I was looking for.
  • Jonas Bartkowski
    Jonas Bartkowski almost 10 years
    But now I have a different problem. When I do only the first two data.put()'s I get this: {race: Human, name: Silenthand Olleander} in the YAML. Only if I add the third put, I get: traits: [ONE_HAND, ONE_EYE] race: Human name: Silenthand Olleander like it should be. Do you have any ideas why this is?
  • Jonas Bartkowski
    Jonas Bartkowski almost 10 years
    It's still "correct" as I can read the right values from their corresponding fields but this layout is less readable than when every value has it's own line. I guess it's to make documents more compact but I would prefer to be able to change it.
  • ig0774
    ig0774 almost 10 years
    There's not a lot of space to explain here, but you can force the item per line by creating a DumperOptions object and setting it to use FlowStyle.BLOCK. See the code from testDumperOptionsFlowStyle() for an example of this.
  • dmitryvim
    dmitryvim about 7 years
    how can dump object(not map) to yaml?