BufferedReader - 通过令牌而不是readLine()读取?

时间:2016-05-29 04:58:23

标签: java bufferedreader

有没有办法从BufferedReader读取,直到它到达不是换行符或返回载符的char(这是readLine()的作用)?

我不想读一行然后拆分。我想忽略换行符并返回托架,并且只考虑具有BufferedReader性能的特定标记(例如标签)。

4 个答案:

答案 0 :(得分:2)

对于这样的事情,你甚至不应该使用BufferedReader。我会像这样使用NIO:

public String[] splitContentsBy(String split, File file){
    try{
        byte[] bytes = Files.readAllBytes(file);
        String contents = new String(bytes);
        String[] array = contents.spilt(split);
    }catch(IOException e){
        e.printStackTrace();
    }
}

如果你只想要一个角色,你可以拥有:

char c = '?'; //A question mark, as an example.
String[] parts = splitContentsBy(String.valueOf(c), new File("file.txt");

答案 1 :(得分:1)

是的确定。

 BufferedReader br = ...
 StringBuilder sb = new StringBuilder(ESTIMATED_LENGTH);
 int ch;
 while ((ch = br.read()) != -1 && ch != '\t') {
     sb.append(ch);
 } 

在最好的情况下,您将获得与BufferedReader.readLine()几乎一样好的性能。在最坏的情况下,你执行一到两个额外的字符副本(我认为)......这对于性能命中 1 而言并不算太差。

获得与BufferedReader一样好的性能将需要破解代码BufferedReader本身...或重写它。

(您尝试扩展BufferedReader不起作用,因为您正在从父类调用private方法。这是不允许的!如果您要通过更改方法访问来“修复”该方法那么你也可以“克隆”BufferedReader类并将你的方法添加到它中。当然,你的类不再是java.io.BufferedReader或它的子类。)

1 - 通过辩护,考虑大局。如果您从某个地方读取大量数据,性能瓶颈很可能是I / O或读取后使用令牌执行的操作。如果情况并非如此,那么您应该使用1)java.nio / CharBuffer,2)自定义I / O堆栈或3)另一种编程语言。

答案 2 :(得分:0)

这不是很优雅,但可能有用。

  1. 将openfferedddd BufferedReader源复制到另一个包中(JVM不会让你的类加载器覆盖任何默认的Java类)。你可以从这里得到它 - http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/io/BufferedReader.java/?v=source
  2. 创建一个从此BufferedReader副本扩展的子类,创建构造函数并覆盖readLine()。复制原始readLine()实现并粘贴为重写readLine()
  3. 将阻止编译的超类(BufferedReeader)中的所有属性和方法从私有更改为受保护
  4. 将所有提及替换为子类readLine()中的\ n和] r代替\ t(因此您将按标签拆分)
  5. voilà: - )

    这就是它最终的样子

    import java.io.IOException;
    import java.io.Reader;
    
    public class MyBufferedReader extends BufferedReader {
    
        /**
         * 
         * @param in
         */
        public MyBufferedReader(Reader in) {
            super(in);
    
        }
    
        @Override
        String readLine(boolean ignoreLF) throws IOException {
            StringBuffer s = null;
            int startChar;
    
            synchronized (lock) {
                ensureOpen();
                boolean omitLF = ignoreLF || skipLF;
    
            bufferLoop:
                for (;;) {
    
                    if (nextChar >= nChars)
                        fill();
                    if (nextChar >= nChars) { /* EOF */
                        if (s != null && s.length() > 0)
                            return s.toString();
                        else
                            return null;
                    }
                    boolean eol = false;
                    char c = 0;
                    int i;
    
                    /* Skip a leftover '\n', if necessary */
                    if (omitLF && (cb[nextChar] == '\t'))
                        nextChar++;
                    skipLF = false;
                    omitLF = false;
    
                charLoop:
                    for (i = nextChar; i < nChars; i++) {
                        c = cb[i];
                        if (c == '\t') {
                            eol = true;
                            break charLoop;
                        }
                    }
    
                    startChar = nextChar;
                    nextChar = i;
    
                    if (eol) {
                        String str;
                        if (s == null) {
                            str = new String(cb, startChar, i - startChar);
                        } else {
                            s.append(cb, startChar, i - startChar);
                            str = s.toString();
                        }
                        nextChar++;
                        if (c == '\t') {
                            skipLF = true;
                        }
                        return str;
                    }
    
                    if (s == null)
                        s = new StringBuffer(defaultExpectedLineLength);
                    s.append(cb, startChar, i - startChar);
                }
            }
        }
    
    }
    

    你可以像这样使用它

        MyBufferedReader my = new MyBufferedReader(new InputStreamReader(Main.class.getResourceAsStream("fileWithTabs.txt")));
        String line = null;
        while((line = my.readLine())!=null) {
            System.out.println(line);
        }
        my.close();
    

    对于像这样的输入

    some string some other string
    some third string after a newline   some forth  
    and so on
    

    结果是

    some string
    some other string
    some third string after a newline
    some forth
    
    and so on
    

    然而,看起来是一个非常非常麻烦的解决方案,所以我真的希望在这里看到其他聪明的答案

答案 3 :(得分:0)

要忽略新行并返回,只需将readLine参数设置为: String readLine(true); 并实现条件检测标签。