Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在行大小不固定的UTF-8编码文本文件上使用Java进行二进制搜索_Java_File Io_Binary Search - Fatal编程技术网

在行大小不固定的UTF-8编码文本文件上使用Java进行二进制搜索

在行大小不固定的UTF-8编码文本文件上使用Java进行二进制搜索,java,file-io,binary-search,Java,File Io,Binary Search,我有一个选项卡分隔的UTF-8文件,其中记录按一个字段排序。但是,线的大小不是固定的,因此不能直接跳到特定的位置。我如何对此进行二进制搜索 例如: 第1行:阿尔弗雷德·布伦德尔/m/011hww/m/0crsgs6、/m/0crvt9h、/m/0cs5n_1、/m/0crtj4t、/m/0crwpnw、/m/0cr_n2s、/m/0crsgyh 第2行:Rupert Sheldrake/m/011ybj/m/0crtsz您知道孔文件包含的字节数。比如说n ->搜索间隔[l,r]与l=0,r=n

我有一个选项卡分隔的UTF-8文件,其中记录按一个字段排序。但是,线的大小不是固定的,因此不能直接跳到特定的位置。我如何对此进行二进制搜索

例如:

第1行:阿尔弗雷德·布伦德尔/m/011hww/m/0crsgs6、/m/0crvt9h、/m/0cs5n_1、/m/0crtj4t、/m/0crwpnw、/m/0cr_n2s、/m/0crsgyh


第2行:Rupert Sheldrake/m/011ybj/m/0crtsz

您知道孔文件包含的字节数。比如说
n
->搜索间隔
[l,r]
l=0
r=n

  • 估计搜索间隔的中间值
    m=(r-l)/2
    。在此位置向左移动尽可能多的字节(也可以向右移动),直到找到制表符(字节==9(9是制表符的ASCII和UTF8代码))[让我们命名此位置
    mReal
    ],并解码该制表符开头的一行

  • 确定在下一个搜索步骤中,您是否必须使用前半部分(=>新搜索间隔为
    [l,mReal]
    )或后半部分(=>新搜索间隔为
    [mReal,r]


我想你可以从文件大小猜出行的长度


然而,当你甚至猜不到行的长度时,我认为最好从生成随机数中进行选择。

你可以跳到字节的中间。从那里你可以找到那一行的结尾,你可以从那一点读下一行。如果你需要向后搜索,每次取四分之一点或四分之三点,然后找到那条线。最终你会把它缩小到一行。

你说的行大小不固定是什么意思?你能展示一个测试用例吗?简言之,他的意思是每一行的长度不是均匀的。(为了向其他读者澄清)你能详细说明一下吗?对不起,我没有得到你的解决方案。请你详细说明一下好吗?@BlackPlanet:至少在我的计算机上\t==9[在ASCII和UTF8中]我的评论并不是想暗示你在ASCII代码上是错误的,只是不清楚你所说的byte==9是什么意思。@BlackPlanet:对不起,我误解了你的评论[有时在你不是母语人士时发生]即使对以英语为母语的人来说,这个词的意思也是模棱两可的。不用担心。你能详细说明一下如何在文件的二进制搜索中使用它吗?这将为你提供所有由EPF_EOL字符串分隔的令牌。因此,您可以轻松接收所有字段
public class YourTokenizer {

    public static final String EPF_EOL = "\t";

    public static final int READ_SIZE = 4 * 1024 ;

    /** The EPF stream buffer. */
    private StringBuilder buffer = new StringBuilder();

    /** The EPF stream. */
    private InputStream stream = null;

    public YourTokenizer(final InputStream stream) {
        this.stream = stream;
    }

    private String getNextLine() throws IOException {
        int pos = buffer.indexOf(EPF_EOL);
        if (pos == -1) {
            // eof-of-line sequence isn't available yet, read more of the file
            final byte[] bytes = new byte[READ_SIZE];
            final int readSize = stream.read(bytes, 0, READ_SIZE);


            buffer.append(new String(bytes));
            pos = buffer.indexOf(EPF_EOL);
            if (pos == -1) {
                if (readSize < READ_SIZE) {
                    // we have reached the end of the stream and what we're looking for still can't be found
                    throw new IOException("Premature end of stream");
                }
                return getNextLine();
            }
        }

        final String data = buffer.substring(0, pos);
        pos += EPF_EOL.length();
        buffer = buffer.delete(0, pos);
        return data;
    }

}
final InputStream stream = new FileInputStream(file);
 final YourTokenizer tokenizer = new YourTokenizer(stream);

 String line = tokenizer.getNextLine();
 while(line != line) {
   //do something
   line = tokenizer.getNextLine();
 }