Question

I have a writeScore.class which is doing the following:

  • Get URL and than InputStream of a relative file score.xml
  • Start building new xml document by parsing through existing one
  • Append new record to the document builder

The last thing the program does should be to write the new document in a place of the old one. Sadly I can't find any way to use the relative path I already have. I've tried to use the use URLConnection and than .getOutputStream, but I get the protocol doesn't support output error. I also gave a try to OIUtils.copy(is, os) to convert InputStream into OutputStream but although there are no errors, for some reason the file doesn't change and the last modification date points to the last time I did it with direct file address. (I did a system wide search in case new file was created somewhere else, found nothing).

Here is simplified code using the URLConnection method:

public class writeScore {

public writeScore(Score NewScore, Interface obj) {
    try {

        // prepare file path
        URL scoreUrl = new URL("file","localhost","save/score.xml");
        InputStream is = scoreUrl.openStream();
        final URLConnection scoreCon = scoreUrl.openConnection();
        final OutputStream os = scoreCon.getOutputStream();

        // build the document
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document doc = docBuilder.parse(is);

        // root element
        Element root = doc.getDocumentElement();
        Element rootElement = doc.getDocumentElement();

        // add new save
        /* removed for code cleaning */

        // save source
        DOMSource source = new DOMSource(doc);

        // set up the transformer
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();

        // add properties of the output file
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        // save the file
        StreamResult result = new StreamResult(os);

        transformer.transform(source, result);

    } // and catch all the exceptions
}
}

If need be I'm happy to change the way I input the file as well, as long I can have a relative path from Java/bin/game/writeScore.class to Java/save/score.xml where 'Java' is my project directory. But also once the game is package into a .jar and save is a folder outside of that jar.

Was it helpful?

Solution

Just use new File("name") that creates a file in the current working directory. With new File("../name") you create a file in the parent directory. You then need to wrap the file in a FileOutputStream.

But I would consinder using JAXB.unmarshal(file, clazz) for reading and JAXB.marshal(object, file) for writing. Just delete the old file before you write the new one. I never had troubles with updating resp. overwriting.

Here is how I did it, I removed the exception handling and logging. Pretty concise and generic, too.

public static <T> void writeXml(T obj, File f)
  {
      JAXB.marshal(obj, f);
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top