gpt4 book ai didi

java - 使用 RandomAccessFile 读取单个 UTF-8 字符

转载 作者:行者123 更新时间:2023-11-30 06:49:44 24 4
gpt4 key购买 nike

我已经设置了一个顺序扫描器,其中指向我的文件的 RandomAccessFile 能够通过以下方法读取单个字符:

public char nextChar() {
try {
seekPointer++;
int i = source.read();
return i > -1 ? (char) i : '\0'; // INFO: EOF character is -1.
} catch (IOException e) {
e.printStackTrace();
}
return '\0';
}

seekPointer 只是我程序的一个引用,但是该方法将 source.read() 存储在一个 int 中,然后返回如果它不是文件的末尾,它会转换为 char。但是我收到的这些字符是 ASCII 格式的,事实上它太糟糕了,我什至不能使用像 ç 这样的符号。

有没有一种方法可以让我接收一个单个字符,它是 UTF-8 格式或至少允许 ASCII 字符集以外的标准化格式?

我知道我可以使用 readUTF() 但它会将整行作为字符串返回,这不是我想要的。

此外,我不能简单地使用另一个流读取器,因为我的程序需要一个 seek(int) 函数,允许我在文件中来回移动。

最佳答案

根据 Willis Blackburn 的回答,我可以简单地进行一些整数检查以确保它们超过一定数量,以获得我需要提前检查的字符数量。

根据下表判断:

first byte starts with 0                         1 byte char
first byte starts with 10 >= 128 && <= 191 ? byte(s) char
first byte starts with 11 >= 192 2 bytes char
first byte starts with 111 >= 224 3 bytes char
first byte starts with 1111 >= 240 4 bytes char

我们可以通过将它与中间列中的数字进行比较来检查从 RandomAccessFile.read() 中读取的整数,这些数字实际上只是一个字节的整数表示。这使我们能够完全跳过字节转换,从而节省时间。

以下代码将从 RandomAccessFile 中读取一个字节长度为 1-4 的字符:

int seekPointer = 0;
RandomAccessFile source; // initialise in your own way

public void seek(int shift) {
seekPointer += shift;
if (seekPointer < 0) seekPointer = 0;
try {
source.seek(seekPointer);
} catch (IOException e) {
e.printStackTrace();
}
}

private int byteCheck(int chr) {
if (chr == -1) return 1; // eof
int i = 1; // theres always atleast one byte
if (chr >= 192) i++; // 2 bytes
if (chr >= 224) i++; // 3 bytes
if (chr >= 240) i++; // 4 bytes
if (chr >= 128 && chr <= 191) i = -1; // woops, we're halfway through a char!
return i;
}

public char nextChar() {
try {
seekPointer++;
int i = source.read();

if (byteCheck(i) == -1) {
boolean malformed = true;
for (int k = 0; k < 4; k++) { // Iterate 3 times.
// we only iterate 3 times because the maximum size of a utf-8 char is 4 bytes.
// any further and we may possibly interrupt the other chars.
seek(-1);
i = source.read();
if (byteCheck(i) != -1) {
malformed = false;
break;
}
}
if (malformed) {
seek(3);
throw new UTFDataFormatException("Malformed UTF char at position: " + seekPointer);
}
}

byte[] chrs = new byte[byteCheck(i)];
chrs[0] = (byte) i;

for (int j = 1; j < chrs.length; j++) {
seekPointer++;
chrs[j] = (byte) source.read();
}

return i > -1 ? new String(chrs, Charset.forName("UTF-8")).charAt(0) : '\0'; // EOF character is -1.
} catch (IOException e) {
e.printStackTrace();
}
return '\0';
}

关于java - 使用 RandomAccessFile 读取单个 UTF-8 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42309110/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com