从socket intputStream read()返回的Int中获取字节

时间:2013-08-15 16:51:54

标签: java sockets byte

我有一个InputStream,我想读取每个char,直到从套接字中找到逗号“,”。

继承我的代码

private static Packet readPacket(InputStream is) throws Exception
{
    int ch;
    Packet p = new Packet();

    String type = "";
    while((ch = is.read()) != 44) //44 is the "," in ISO-8859-1 codification
    {
        if(ch == -1)
            throw new IOException("EOF");
        type += new String(ch, "ISO-8859-1"); //<----DOES NOT COMPILE
    }
    ...
}

String构造函数不接收int,只接收一个字节数组。我阅读了文档,并说它

读(): 从输入流中读取下一个数据字节。

如何将此int转换为byte呢?它是仅使用int的所有32位的较低有效位(8位)吗?

由于我正在使用Java,我希望保持完全平台兼容(小端与大端等等)。这里最好的方法是什么?为什么?

PS:我不想使用任何现成的类,如DataInputStream等....

4 个答案:

答案 0 :(得分:2)

String构造函数采用char [](数组)

type += new String(new byte[] { (byte) ch }, "ISO-8859-1");

顺便说一下。将 StringBuilder 用于类型并使用其append-methods会更优雅。它更快,也更好地显示出意图:

private static Packet readPacket(InputStream is) throws Exception {
    int ch;
    Packet p = new Packet();

    StringBuilder type = new StringBuilder();
    while((ch = is.read()) != 44) {
        if(ch == -1)
            throw new IOException("EOF");
        // NOTE: conversion from byte to char here is iffy, this works for ISO8859-1/US-ASCII
        // but fails horribly for UTF etc.
        type.append((char) ch);
    }
    String data = type.toString();
    ...
}

另外,为了使其更灵活(例如使用其他字符编码),您的方法最好采用一个InputStreamReader来处理从字节到字符的转换(请查看InputStreamReader(InputStream,Charset)构造函数的javadoc)。

答案 1 :(得分:2)

为此可以使用InputStreamReader,它可以读取原始字节流中的编码字符数据:

InputStreamReader reader = new InputStreamReader(is, "ISO-8859-1");

您现在可以使用reader.read(),它将使用is中正确的字节数,解码为ISO-8859-1,并返回可以正确地投射到char

编辑:回应关于不使用任何“即用型”课程的评论:

我不知道InputStreamReader是否重要。如果是,请查看Durandal的答案,这对于某些单字节编码就足够了(如US-ASCII,可论证或ISO-8859-1)。

对于多字节编码,如果您不想使用任何其他类,则首先将所有数据缓冲到byte[]数组中,然后从中构造String

编辑:回复关于Abhishek答案的评论中的相关问题。

问:

  

Abhishek写道:你能再多开导一下吗?我已经尝试将整数ASCII转换为字符..它已经工作了..你能告诉我哪里出错了吗?

A:

你本人并没有“错误”。 ASCII工作的原因与Brian指出ISO-8859-1的工作原理相同。 US-ASCII是单字节编码,字节0x00-0x7f与其对应的Unicode代码点具有相同的值。因此,对char的转换在概念上是不正确的,但在实践中,由于值是相同的,因此它可以工作。与ISO-8859-1相同; bytes 0x00-0xff与该编码中的相应代码点具有相同的值。对char的强制转换不适用于例如IBM01141(单字节编码但具有不同的值)。

当然,char cast的单个字节对UTF-16等多字节编码不起作用,因为必须读取多个输入字节(实际上是一个变量号)来确定相应的正确值炭。

答案 2 :(得分:0)

部分答案:尝试更换:

  type += new String(ch, "ISO-8859-1");

通过

  type+=(char)ch;

如果您收到char.Code的ASCII值,则可以通过强制转换将ASCII转换为char。

最好避免冗长的代码,这样可以正常工作。 read()函数以多种方式工作:

一种方法是:int= inpstr.read();

第二个inpstr.read(byte) 因此,你想要使用哪种方法......两者都有不同的目的..

答案 3 :(得分:0)

type += new String(String.valueOf(ch).getBytes("ISO-8859-1"));