0

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

这是我的代码

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,只接收字节数组。我阅读了文档,它说

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

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

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

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

4

4 回答 4

2

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

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

您现在可以使用reader.read(),它将消耗来自 的正确字节数is,解码为 ISO-8859-1,并返回一个可以正确转换为char.

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

不知道InputStreamReader算不算 如果是这样,请查看 Durandal 的答案,这对于某些单字节编码(如 US-ASCII、arguable 或 ISO-8859-1)来说已经足够了。

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

编辑:在对 Abhishek 的回答的评论中回答相关问题。

问:

Abhishek 写道: 你能多指教一下吗?我已经尝试将整数 ASCII 转换为字符..它有效..你能告诉我哪里出错了吗?

A:

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

而且,当然,单字节到字符转换对于像 UTF-16 这样的多字节编码不起作用,因为必须读取多个输入字节(实际上是一个可变数字)才能确定相应字符的正确值。

于 2013-08-15T17:06:14.820 回答
2

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

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

顺便提一句。使用StringBuilder作为类型并利用其附加方法会更优雅。它更快,也更好地显示了意图:

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)。

于 2013-08-15T16:59:15.487 回答
0

部分答案:尝试更换:

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

经过

  type+=(char)ch;

如果您收到 char 的 ASCII 值,则可以这样做。代码通过强制转换将 ASCII 转换为 char。

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

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

其次inpstr.read(byte) ,这取决于您要使用哪种方法..两者都有不同的目的..

于 2013-08-15T16:56:38.677 回答
0
type += new String(String.valueOf(ch).getBytes("ISO-8859-1"));
于 2013-08-15T16:57:37.057 回答