一个换行符引起的死亡场景

来源:互联网 发布:卡尔软件 编辑:程序博客网 时间:2024/06/10 11:57

在开发生涯中我们许多时候会很亲赖于BufferedReader,特别是它的readLine()方法简直就是我们的福音。但是我们在做流传输的时候如果没有传输换行符或者流结束符会怎么样呢?

看下面的场景:

import java.io.*;/** * Created by dushangkui on 2017/6/2. */public class TestLine {    public static void main(String[] args) throws IOException {        InputStream is = new InputStream() {            int index=0;            char[] data = {'d','u','s','k'};            @Override            public int read() throws IOException {                if(index<4)                    return data[index++];                else                    return 20;//换行符'\n'是10 流结束的符号EOF是-1            }        };        BufferedReader br = new BufferedReader(new InputStreamReader(is));        System.out.print(br.readLine());    }}

我们期望的结果是输出 dusk 结果呢?


直接读到内存溢出也没打印出我们想要的dusk。

我们看正常情况

public class TestLine {    public static void main(String[] args) throws IOException {        InputStream is = new InputStream() {            int index=0;            char[] data = {'d','u','s','k'};            @Override            public int read() throws IOException {                if(index<4)                    return data[index++];                else                    return '\n';//换行符'\n'是10 流结束的符号EOF是-1            }        };        BufferedReader br = new BufferedReader(new InputStreamReader(is));        System.out.print(br.readLine());    }}


运行结果是:


从中我们可以知道,如果流写入的时候没有写入换行符或者结束符的时候,你想在另一头读取出来是不可能的。这是因为BufferedReader的readLine方法实现定义的:

 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] == '\n'))                    nextChar++;                skipLF = false;                omitLF = false;            charLoop:                for (i = nextChar; i < nChars; i++) {                    c = cb[i];                    if ((c == '\n') || (c == '\r')) {                        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 == '\r') {                        skipLF = true;                    }                    return str;                }                if (s == null)                    s = new StringBuffer(defaultExpectedLineLength);                s.append(cb, startChar, i - startChar);            }        }    }

得不到我就一直读

原创粉丝点击