Question

I'm trying to write line into a file at line-position n.

Even if line n isn't present. In that case the file has to grow with empty lines to reach n. Basically something like writer.writeLine(n, mycontent). mycontent is a binary representation from ObjectOutputStream. Each line of the file contains a serialized object. The line-number is the index.

How can I write to a specific line? - Without using FileUtils or any non-standard API components.

This answer pretty much sums up what I want - but with writing it seems to behave different.

edit: I clarified my question due to the comments

Was it helpful?

Solution

Is the notion of line is very important to you? Otherwise you could probably serialize a Map in a file, and use it to write or read your objects at a specific index (in that case, the index would be key of the map).

Here's a little example.

    public static void main(String[] args) throws Exception {
    ObjectOutputStream tocStream = new ObjectOutputStream(new FileOutputStream("myfile.toc"));
    Map<Integer,Object> tableOfContent = new HashMap<Integer, Object>();
    String myString = "dataOne";
    Date myDate = new Date();
    tableOfContent.put(0,myDate);
    tableOfContent.put(1,myString);
    tocStream.writeObject(tableOfContent);
    tocStream.flush();
    tocStream.close();
    ObjectInputStream tocInputStream = new ObjectInputStream(new FileInputStream("myfile.toc"));
    Map<Integer,Object> restoredTableOfContent = (Map<Integer, Object>) tocInputStream.readObject();
    Object restoredMyString  =  restoredTableOfContent.get(1);
    System.out.println(restoredMyString);
    tocInputStream.close();
}

OTHER TIPS

This won't work, because each serialized object might contain one or several newline character(s) as part of the its binary representation. So if you write a new object at line 3, you might very well write the object in the middle of the binary representation of your first one. Test it :

public class OOSTest {
    public static void main(String[] args) throws IOException {
        String s = "Hello\nWorld";
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(s);
        oos.flush();
        oos.close();
        System.out.println(new String(bos.toByteArray()));
    }
}

IMHO, you have three choices:

  1. Choose a protocol which will work with binary data (for example: for each object, write its length (in bytes) as an integer (4 bytes) followed with the bytes of the object itself;
  2. Encode the serialized bytes into a string, using Base64 for example, and use a separator between the objects which is not part of the encoding;
  3. Use an ObjectOutputStream to serialize an array of Objects. Writing a new entry would consist in deserializing the array, make sure it has the right size or copy it to a new array of the appropriate size, insert your object at its position, and reserialize the whole array.
  • Loop through the file reading the current values.
  • Write each value out to a new temp file.
  • If the old file ends before your line number keep writing out blank lines.
  • Then once you get to the line number you want to update write out the new data.
  • If there is more lines to the old file keep writing.
  • Delete the old file. Rename the temp file.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top