0

I need to write a string in a file as bytes in UTF-8 and then get these bytes back from file and convert it back to string and as a consiquence get the same string. May be it sounds easy but there is a hidden problem such as incorrect symbols in file. I mean that after appending in file it must contain something like:

00000008 d0bad0bb d18ed187 00000010 etc...

But it contains stuff like that:

mystring ---a lot of space--- (and the symbol that doesn't display here)

So, what have I already done? I've tried this way:

Before code read this: I keep strings in HashMap < String, String > that's why my code contains get(...) etc.

try {
        FileOutputStream oStream = new FileOutputStream("filename.txt");
        Set<String> keySet = storage.keySet();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        for (String key : keySet) {
            byte[] keyInByte = key.getBytes("UTF-8");
            byte[] valueInByte = storage.get(key).getBytes("UTF-8");
            oStream.write(buffer.putInt(0, valueInByte.length).array());
            oStream.write(keyInByte);

            oStream.write((buffer.putInt(0, valueInByte.length).array()));
            oStream.write(valueInByte);
        }
    } catch (Exception e) {
        System.err.println("permission denied");
    }

I have also tried use PrintWriter, FileWriter, etc... but it doesn't give what I need. For example, some of them need toString() method but after toString() I will lose the ability to work with bytes.

! Notice, that I've tried to change my notepad to UTF-8 encode, but it gives no result.

15
  • Why not use PrintWriter and BufferedReader as the file will always be bytes in the end anyway. They will be simpler, and possibly faster. Normally .txt means text not binary. BTW DataInput/OuputStream as a writeUTF/readUTF method which does something like this more efficiently. Commented Oct 8, 2014 at 21:44
  • @PeterLawrey As I mentioned I've tried many ways including PrintWriter, it needs to use toString() method for my operations. So then I will loose the ability to work with bytes correctly. Commented Oct 8, 2014 at 21:46
  • Not sure why you can't do that with Reader/Writer. From your description it appears your problem is that you are using binary and not text. but if you need a binary format you can use data streams. Commented Oct 8, 2014 at 21:53
  • @PeterLawrey Could you write some code? May be there's a solution that I don't unserstand... Commented Oct 8, 2014 at 21:56
  • A specific example would depend on your requirements, for example, I wouldn't write the length in a text file, only in a binary file. Writing the length makes editing the file unreasonably harder to edit. (With a binary format editing the file is not an option) It's also not clear to me if you want text or binary. BTW You should always print out an exception as there could be many causes. Commented Oct 8, 2014 at 22:07

1 Answer 1

2

If you want to use Properties you can do this.

new Properties(map).save(new FileOutputStream("filename.proeprties"));

to load the properties

Properties prop = new Properties();
prop.load(new FileInputStream("filename.properties"));
map.putAll(prop);

To save copying the data you can use Properties as a Map.

key1=value1
key2=value2

Note: a key cannot contain a = or a newline.


This is how I would do it in a binary format

DataOutputStream dos = new BufferedOutputStream(new FileOutputStream("filename.dat")));
dos.writeInt(map.size());
for (Map.Entry<String, String> entry : map.entrySet()) {
    dos.writeUTF(entry.getKey());
    dos.writeUTF(entry.getValue());
}
dos.close();

This is how I would write it in text, using UTF-8

PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOuputStream("filename.txt") "UTF-8"));
pw.println(map.size());
for (Map.Entry<String, String> entry : map.entrySet()) {
     pw.println(encode(entry.getKey()));
     pw.println(encode(entry.getValue()));
}
pw.close();


public static String encode(String s) {
    // if you can assume no new lines, don't do anything.
    return s.replaceAll("\\\\", "\\\\\\\\").replaceAll("\n", "\\\\n");
}

This will produce a like like

key1
value1
key2
value2

This you can edit fairly easy. If youc an assume the key doesn't have an = or : or tab, you can use one line like a properties file

Sign up to request clarification or add additional context in comments.

9 Comments

Thank You! You really helped me. But I have one more question: return s.replaceAll("\\", "\\\\").replaceAll("\n", "\\n"); doesn't work because of "\\" and "\\\\". Should I use "//" instead? BTW I use intellij IDEA on Windows 8.1 if that matters =) I'm sorry for stupid questions, I'm just new at Java.
What do you mean it doesn't work? Btw I have intellij on win 8.1 as well.
@PeterLawrey I am guessing that "doesn't work" means "throws exception" because replaceAll uses regex as argument and "\\" is incorrect regex in Java (it is like writing \ as regex which is wrong because \ needs something after it like \s or \d or \\). Maybe you wanted to use replace instead of replaceAll?
replaceAll("\\\\", "\\\\") have no sense :/ (you are replacing one \ with one \ because \ is also special in replacement part - it can be used with "\\$" to represent $ literal because $ itself is also special because it can be used like "$1" to let us use in replacement match stored in group 1). If you want to replace one \ with two \\ either use replaceAll("\\\\", "\\\\\\\\") or to avoid regex confusion replace("\\","\\\\").
Yes, second argument is string, but this argument is not just any string, because it also is used by regex engine while replacing, and can contain some special characters, which are $ - reference to match from group matched by regex (for instance $1 represents match from group 1), \ to let us escape $, so to represent \ literal in this second argument you need to write it as "\\\\".
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.