Java's DataInputStream.readUTF and number of bytes read
Asked Answered
A

4

5

I am writing a custom archive format in JAVA (J2ME to be precise). The archiver works OK, however I have little problems with de-archiving.

How could I know how many bytes have been read when reading a UTF8 string thorough the readUTF method? I know that the first two bytes of a string saved using writeUTF are a short value of the string's length, but I'd like a nicer solution.

Or is there any way to know how many bytes are left till the end of the DataInputStream (the available method doesn't seem to return meaningful values). The stream was opened by a FileConnection, i.e. FileConnection.openDataInputStream.

Thanks guys!

Atrice answered 24/7, 2010 at 11:13 Comment(0)
I
4

I can't see a way of achieving this using the CLDC API directly. A simple solution however, would be to roll your own "CountingInputStream" that extends InputStream and counts the number of bytes read. You would basically just need to override the three read-methods.

The file size is available through the FileConnection.

Improvised answered 24/7, 2010 at 13:18 Comment(2)
I know about the fileSize(). I agree about CountingInputStream, but this looks ugly (at least to me).Atrice
I see your point, but I don't think it's that ugly. Such a class is fairly useful and definitely reusable, also in other situations than for FileConnections. And even if it is slightly ugly, it's encapsulated and stowed away in a small class.Improvised
L
2

This may be a bit late, but I've recently been working on something where I needed to know the amount of bytes that have been read, as opposed to how many are left to be read, as this question asks. But you can derive that number from the solution that I've got. I wanted to know the amount of bytes read so I could monitor the download's progress (in case it took a while).

I was initially just using DataInputStream#readFully() to download the files.

buffer = new byte[length];
in.readFully(buffer);

But sometimes I was left waiting for anywhere from 50 - 60 seconds for the download to complete, depending on the size. I wanted to get real-time updates on how things were going, so I changed to use just the regular DataInputStream#read(byte[] b, int off, int len). So there's a System.out there at the end telling me whenever I've jumped a percentage point:

buffer = new byte[length];
int totalRead = 0;
int percentage = 0;

while (totalRead < length)
{
    int bytesRead = in.read(buffer, totalRead, (length - totalRead));

    if (bytesRead < 0)
        throw new IOException("Data stream ended prematurely");

    totalRead += bytesRead;
    double progress = ((totalRead*1.0) / length) * 100;
    if ((int)progress > percentage)
    {
        percentage = (int)progress;
        System.out.println("Downloading: " + percentage + "%");
    }
}

To know how many bytes remain to be read, some minor modifications can be made to the last example. Having a tracker variable in place of my percentage, for example:

buffer = new byte[length];
int totalRead = 0;
int bytesLeft= 0;

while (totalRead < length)
{
    bytesLeft = length - totalRead;
    int bytesRead = in.read(buffer, totalRead, bytesLeft);

    if (bytesRead < 0)
        throw new IOException("Data stream ended prematurely");

    totalRead += bytesRead;
    System.out.println("Bytes left to read: " + bytesLeft);
}
Lorislorita answered 16/5, 2012 at 5:48 Comment(0)
P
2

This is a fairly old question, but I'll post my solution as it might help someone:

There is actually a convenient CountingInputStream wrapper in Apache Commons IO http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CountingInputStream.html

It's derived from java.io.FilterInputStream so you can basically wrap it around any standard input stream.

In your case, assuming dataInputStream variable denotes the stream you work with:

CountingInputStream counter = new CountingInputStream( dataInputStream );
dataInputStream = new DataInputStream( counter );
...
counter.getByteCount() //this returns num of bytes read from dataInputStream
Pacian answered 5/4, 2013 at 15:16 Comment(0)
S
1

The available() method returns what it is documented to return, which isn't what you are trying to use it for. See the Javadoc.

You could write your own byte-counting FilterInputStream and put it between the data input stream and the underlying stream. But you'll have to get the total byte count of the source from the source, that information isn't available to any input stream.

Shower answered 24/7, 2010 at 13:18 Comment(4)
AFAIK, FilterInputStream is not available on the MID Profile.Improvised
Doesn't really matter, you can write it all yourself just as easily.Shower
Also do you really need these byte counts? You will get EOF indications when you get to the end of the stream ...Shower
I know what the documentation says about available(). Easiest way will be to rewrite the structure of the archive format. Now it is like that archive_header, (file_header, content)* I'll just put the headers at one place in the end. Anyway, my asking was regarding the fact that it's strange that there is no "official" way of getting to know how many actual bytes have been read. Thank you all!Atrice

© 2022 - 2024 — McMap. All rights reserved.