0
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestEOF {
    // Throw exceptions to console:
    public static void main(String[] args) throws IOException {
        DataInputStream in = new DataInputStream(new BufferedInputStream(
                new FileInputStream("TestEOF.txt")));
        while (in.available() != 0)
            System.out.print((char)(in.readByte()));
        //testDataOutputStream
        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(
                new FileOutputStream("ABC.txt")));
        out.writeDouble(12.33333333);
        out.writeDouble(82918293.3334893320109);
                out.flush();
        DataInputStream dis = new DataInputStream(new BufferedInputStream(
                new FileInputStream("ABC.txt")));
        while (dis.available() != 0)
            System.out.print(Byte.toString(dis.readByte()));
                          System.out.println(dis.readByte());
    }
} // /:~

Hi, guys. I thought char needs two bytes in java, so "System.out.print((char)(in.readByte()))" cannot work or it should give me wrong answer since every time it converts one byte to a char. However, it works well: Whatever I put in the "TestEOF.txt" file can be printed out correctly.

For the part starting from "//testDataOutputStream", Byte.toString(dis.readByte()) works well, but dis.readByte() throws an exception. It really confuses me.

Anyone can help? Thank you very much.

2 Answers 2

1

The output of TestEOF.txt won't work if the file has some multibyte characters in character encodings other than Unicode 16 and ASCII. The casting happened to work because the contents are coincidentally equal to their multibyte counterpart (because they are in ASCII).

The last line System.out.println(dis.readByte()); throws an EOFException because there is no more content available in the input stream.

EDIT

To retrieve the doubles saved in ABC.txt, simply do something like

DataInputStream dis = new DataInputStream(new FileInputStream("ABC.txt"));

while (dis.available() != 0)
    System.out.println(dis.readDouble());

dis.close();

If you want to know how the data is retrieved and converted, try this

byte[] bBuf = new byte[8];
double d = 0;
long l = 0;

FileInputStream fis = new FileInputStream("ABC.txt");

while(-1 != fis.read(bBuf))
{
    l = (((long) bBuf[0] & 0xff) << 56)
        | (((long) bBuf[1] & 0xff) << 48)
        | (((long) bBuf[2] & 0xff) << 40)
        | (((long) bBuf[3] & 0xff) << 32)
        | (((long) bBuf[4] & 0xff) << 24)
        | (((long) bBuf[5] & 0xff) << 16)
        | (((long) bBuf[6] & 0xff) << 8)
        | ((long) bBuf[7] & 0xff)
        ;
    d = Double.longBitsToDouble(l);
    System.out.println(d);
}

fis.close();
Sign up to request clarification or add additional context in comments.

3 Comments

I should be more careful about my code. the bug of exception is fixed. I check the "ABC.txt" file. I find the content is @(獛桝撃頤U~:, but according to the code some double values should be saved in the file. How can I make the output readable for human beings?
I check the API for writeDouble(double v). It says "Converts the double argument to a long using the doubleToLongBits method in class Double, and then writes that long value to the underlying output stream as an 8-byte quantity, high byte first". I cannot get ideas to store the data in the right way. I mean storing the double values as real numbers in the text file.
@user811416. See my response added to the original answer.
0

This isn't a thorough answer, but hopefully it should get you on the right path.

I would recommend some time learning about character encodings and character sets. While it is true that every character in US-ASCII is encoded into a single byte (so when you read a single byte you can convert it to a single character), this is not always the case. (so a straight cast from one to the other is a bad idea... one method of conversion would be new String(byte[],Charset), and String#getBytes(String) for the opposite direction. Classes that work with reading/writing character data to/from streams often permit the specification of which character encoding (Charset) to use.

By default, if you do not specify an character encoding (which you really always should), Java will attempt to use the platform encoding of your system to read in and write out streams of data. Internally however, Java holds these characters as Unicode characters (specifically UTF-16)

Comments

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.