在Java中将字节流转换为字符流

时间:2011-01-21 03:13:39

标签: java arrays encoding stream character

是否有一个类可以通过指定编码,将字节流输入到它并从中获取字符流来创建它?重点是我想通过同时在内存中同时整个字节流数据和整个字符流数据来节省内存。

类似的东西:

Something s = new Something("utf-8");
s.write(buffer, 0, buffer.length); // it converts the bytes directly to characters internally, so we don't store both
// ... several more s.write() calls
s.close(); // or not needed

String text = s.getString();
// or
char[] text = s.getCharArray();

那是Something

4 个答案:

答案 0 :(得分:6)

您在寻找ByteArrayInputStream吗?然后,您可以将其包装在InputStreamReader中,并从原始字节数组中读取字符。

ByteArrayInputStream允许您从字节数组中“流式传输”。如果将其包裹在InputStreamReader中,则可以读取字符。 InputStreamReader允许您规定字符编码。

如果你想从输入的字节源直接 ,那么你可以构造适当类型的InputStream类(例如FileInputStream)然后换行那是InputStreamReader

答案 1 :(得分:4)

您可以使用CharsetDecoder进行模拟。

的内容
    CharsetDecoder decoder = Charset.forName(encoding).newDecoder();
    CharBuffer cb = CharBuffer.allocate(100);
    decoder.decode(ByteBuffer.wrap(buffer1), cb, false);
    decoder.decode(ByteBuffer.wrap(buffer2), cb, false);
    ...
    decoder.decode(ByteBuffer.wrap(bufferN), cb, true);
    cb.position(0);
    return cb.toString();

(是的,我知道这会溢出您的CharBuffer - 您可能希望将内容复制到StringBuilder。)

答案 2 :(得分:1)

您的示例代码似乎并不表示需要字符流。如果是这样,String已经可以处理您想要的所有内容。假设String s包含数据,

char[] chars = s.toCharArray();
byte[] bytes = s.getBytes("utf-8");

然后问题减少到如何将字节流中的字节转换为String,您可以使用ByteArrayOutputStream,如下所示:

ByteArrayOutputSteam os = new ByteArrayOutputSteam();
os.write(buffer, 0, buffer.length); // it just stores the bytes, doesn't convert yet.
// several more os.write() calls
s = os.toString("utf-8"); // now it converts the full buffer to a string in the specified encoding.

如果你真的想要一个有字节输入流和字符输出流的东西,那就没有内置输入流。

答案 3 :(得分:1)

实际上标题“将字节流转换为Java中的字符流”与您的示例相矛盾,除了数组之外根本不使用任何流。我想进一步想要数组。

你肯定不能以byte []开头并以char [](或String)结束,而不会在某个地方停留一段时间。但是有一些可能性:

  • 如果您确实需要char[]:想法:将byte []写入文件并使用FileReader将其读入数组。这不起作用,因为您事先并不知道正确的数组长度。因此,使用DataOutput生成所有字符并将其写入文件,使用DataInput将所有字符读回数组。

  • 如果您确实需要String:如上所述创建char[]并使用反射和setAccessibe(true)来调用包私有ctor String(int offset, int count, char value[])。< / p>

  • 如果CharSequence足够:创建一个包含byte []的类MyCharSequence。一个非常慢的解决方案是通过从开头开始转换byte []的一部分直到获得charAt(index)字符来实现其方法index+1。在运行中丢弃所有这些并保留最后一个。这样一个愚蠢的方法是必需的,因为使用utf8你不知道有多少字节对应一个char。你可以在开始时做一次并记住每个char的第一个字节的位置。这更加愚蠢,因为你需要为这些职位留下更多的记忆。幸运的是,存在一个简单的时空权衡,例如,记住每个第16个字符的第一个字节的位置。

我的所有建议都有点奇怪,但我相信,它不可能做得更好。这可能是一个有趣的家庭作业,我不会去做。