我需要将字节流转换为UTF-8字符行。在这一行中对我来说唯一重要的角色是最后一个。这种转换应该在一个周期内进行,因此性能非常重要。一种简单而低效的方法是:
public class Foo {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
void next(byte input) {
this.buffer.write(input);
String text = this.buffer.toString("UTF-8"); // this is time consuming
if (text.charAt(text.length() - 1) == THE_CHAR_WE_ARE_WAITING_FOR) {
System.out.println("hurray!");
this.buffer.reset();
}
}
}
字节数组到字符串的转换发生在每个输入字节上,据我所知,这是非常无效的。是否有可能以某种方式保留前一周期的字节到文本转换结果?
答案 0 :(得分:5)
您可以使用一个简单的类来跟踪字符,只有在获得完整的UTF8序列时才能进行转换。这是一个示例(没有您可能想要添加的错误检查)
class UTF8Processor {
private byte[] buffer = new byte[6];
private int count = 0;
public String processByte(byte nextByte) throws UnsupportedEncodingException {
buffer[count++] = nextByte;
if(count == expectedBytes())
{
String result = new String(buffer, 0, count, "UTF-8");
count = 0;
return result;
}
return null;
}
private int expectedBytes() {
int num = buffer[0] & 255;
if(num < 0x80) return 1;
if(num < 0xe0) return 2;
if(num < 0xf0) return 3;
if(num < 0xf8) return 4;
return 5;
}
}
class Bop
{
public static void main (String[] args) throws java.lang.Exception
{
// Create test data.
String str = "Hejsan åäö/漢ya";
byte[] bytes = str.getBytes("UTF-8");
String ch;
// Processes byte by byte, returns a valid UTF8 char when
//there is a complete one to get.
UTF8Processor processor = new UTF8Processor();
for(int i=0; i<bytes.length; i++)
{
if((ch = processor.processByte(bytes[i])) != null)
System.out.println(ch);
}
}
}
答案 1 :(得分:2)
基于评论:
换行(0x0A)
您的next
方法可以检查:
if ((char)input == THE_CHAR_WE_ARE_WAITING_FOR) {
//whatever your logic is.
}
您不必对字符进行任何转换&lt; 128。
答案 2 :(得分:1)
您有两种选择:
如果你感兴趣的代码点是一个简单的(用UTF-8术语)作为128以下的代码点,那么从byte
到char
的简单转换是可能的。查找Wikipadia: UTF-8上的编码规则,了解其工作原理。
如果无法做到这一点,您可以查看Charset
类,它是Java编码/解码库的根。在这里,您将找到CharsetDecoder
,您可以提供N个字节并返回M个字符。一般情况是N!= M.但是,您必须处理ByteBuffer
和CharBuffer
。
答案 3 :(得分:0)
将您的字节获取代码包装在InputStream中并将其传递给InputStreamReader。
InputStreamReader isr = new InputStreamReader(new InputStream() {
@Override
public int read() throws IOException {
return xx();// wherever you get your data from.
}
}, "UTF-8");
while(true) {
try {
if(isr.read() == THE_CHAR_WE_ARE_WAITING_FOR)
System.out.println("hurray!");
} catch(IOException e) {
e.printStackTrace();
}
}