0

I have this code:

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main  {
    public static void main(String[] args) {
        zero("zero.out");
        System.out.println(zeroRead("zero.out"));
    }

    public static String zeroRead(String name)  {

        try (FileInputStream fos = new FileInputStream(name);
             BufferedInputStream bos = new BufferedInputStream(fos);
             DataInputStream dos = new DataInputStream(bos)) {

            StringBuffer inputLine = new StringBuffer();
            String tmp;
            String s = "";
            while ((tmp = dos.readLine()) != null) {
                inputLine.append(tmp);
                System.out.println(tmp);
            }
            dos.close();
            return s;
        }
        catch (IOException e)  {
            e.printStackTrace();
        }

        return null;
    }


    public static void zero(String name)  {
        File file = new File(name);
        String text = "König" + "\t";

        try (FileOutputStream fos = new FileOutputStream(file);
             BufferedOutputStream bos = new BufferedOutputStream(fos);
             DataOutputStream dos = new DataOutputStream(bos)) {

             dos.write(text.getBytes(StandardCharsets.UTF_8));
             dos.writeInt(50);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

zero() method writes data into file: the string is written in UTF-8, while the number is written in binary. zeroRead() read the data from file.

The file looks like this after zero() is executed:

enter image description here

This is what zeroRead() returns:

enter image description here

How do I read the real data König\t50 from the file?

2
  • Note that the method DataInputStream.readLine() is deprecated with comment: "This method does not properly convert bytes to characters" Commented Feb 26, 2021 at 14:45
  • @Jesper System.out.println("König") works fine though. So console can print it. The problem König isn't saved in the String variable in zeroRead(). How do I return the correct string from zeroRead()? Commented Feb 26, 2021 at 14:47

1 Answer 1

3

DataInputStream's readLine method has javadoc that is almost yelling that it doesn't want to be used. You should heed this javadoc: That method is bad and you should not use it. It doesn't do charset encoding.

Your file format is impossible as stated: You have no idea when to stop reading the string and start reading the binary numbers. However, the way you've described things, it sounds like the string is terminated by a newline, so, the \n character.

There is no easy 'just make this filter-reader and call .nextLine on it available, as they tend to buffer. You can try this:

InputStreamReader isr = new InputStreamReader(bos, StandardCharsets.UTF_8);

However, basic readers do not have a readLine method, and if you wrap this in a BufferedReader, it may read past the end (the 'buffer' in that name is not just there for kicks). You'd have to handroll a method that fetches one character at a time, appending them to a stringbuilder, ending on a newline:

StringBuilder out = new StringBuilder();

for (int c = isr.read(); c != -1 && c != '\n'; c = isr.read())
  out.append((char) c);

String line = out.toString();

will get the job done and won't read 'past' the newline and gobble up your binary number.

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

2 Comments

Thank you. It works and I can get König. How do I get the number 50 though? After the \n is reached?
Or just write that code yourself. It's fairly simple - make a 4-byte array, call readFully with that array on the bos, then turn that into an int using one of the static methods int has.

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.