How do I write to a YAML file using SnakeYaml?
Asked Answered
D

4

17

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.

Darren answered 25/7, 2014 at 6:38 Comment(0)
A
25

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.

Appointed answered 25/7, 2014 at 7:52 Comment(4)
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?Darren
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.Darren
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.Appointed
how can dump object(not map) to yaml?Carrier
E
6

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);
}
Enchondroma answered 10/6, 2020 at 14:10 Comment(0)
L
2

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>
Liquorish answered 12/9, 2019 at 7:20 Comment(0)
I
1

I just try all of these methods above and had some results: in the first solution i received data with "{" "}" symbols, I applied code from second solution

final DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setPrettyFlow(true);
final Yaml yaml = new Yaml(options);

and write file if i need. But after I write some times my property.yml. In first time content was OK, but if I read and write again i received binary data instead of value, and application is crashed.

At last i found a solution in that: I read YAML file to Map fill necessary data to it and write Map to file. After many times writes i have correct content in the file.

    try {
 // YAML to Map
            final DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            options.setPrettyFlow(true);
            final Yaml yaml = new Yaml(options);
            Map<String, Object> map = yaml.load(new FileInputStream(path));
 // fill data to map
            map.put("sourceUrl", sourceUrl);
// Map to YAML
            final FileWriter writer = new FileWriter(path);
            yaml.dump(map, writer);
        } catch (IOException e) {
            log.error("Error when we try to save new property.yml");
            throw new RuntimeException(e);
        }

Dependency is:

implementation 'org.yaml:snakeyaml:2.0'

<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
Indemnify answered 7/7, 2023 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.