简体   繁体   中英

Converting InputStream.read() to numbers (not integers)

I've been struggling to get a part of my program working. After about a week of trial and error I don't think I'm able to do this without any help.

Here's the case: I've written an application which, using Sockets, reads data from a device over TCP . All the data sent by the device is represented as bytes, not as strings. Whenever I google on InputStream , all I get is "How to convert InputStream to String".

Currently I'm able to read the data from the InputStream into an ArrayList<Integer> . However, these are Integers, and not decimals.

Here's an example of a (UNIX) TimeStamp sent by the device, read in integers:

0 0 1 80 59 165 176 64 (edited, copied 1 byte too many)

I've tried a lot here, and have not yet succeeded in converting these to a correct UNIX timestamp. It should be translated to 1444109725 (which is 10/06/2015 @ 5:35am (UTC)) .

Anyone who could help me out? Thanks in advance!

-- Edit --

Thanks to all the answers below I've been able to create a working 'parser' for the incoming data. All I had to do was convert the bytes/integers to Long values. As my incoming data consists of multiple values with different lengths it's not possible to read it all as Long, so I had to iterate over te data, grab for example the 8 bytes/integers for the timestamp and use this method to create a readable unix timestamp:

public long bytesToLong(int[] bytes) { 
long v = 0 ; 
for (int i : bytes) { 
v = (v << 8) | i; 
} return v; 
}

It should be translated to 1444109725

Well, I suspect it should actually be translated to 1444109725760, which is what the bytes represent when read as a big-endian 64-bit integer. You then treat that as milliseconds since the Unix epoch (rather than seconds).

Fortunately, this is trivial to do: use DataInputStream , and call readLong . It would be slightly trickier if this were little-endian... but if your format is basically big-endian, you should do as much as you can using DataInputStream ... it'll make your life much simpler.

Agree with the previous answer, using DataInputStream is the best way to go. If you want to get the value by hand:

package snippet;

public class FindLong {

    public static void main(String[] args) {
        int[] bytes = new int[] { 0, 0, 1, 80, 59, 165, 176, 64 } ;

        long v = 0 ;
        for (int i : bytes) {
            v = (v << 8) | i;
        }
        System.out.println(v);
    }
}

Prints 1444109725760 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM