簡體   English   中英

BufferedReader#readLine()即使已讀取一行也會掛起

[英]BufferedReader#readLine() hangs even though a line has been read

更新的問題(更清楚):

有沒有辦法在下面設計InputStream,以便在讀取新行字符后BufferedReader#readLine()將返回?

在下面的示例中, readLine()永遠掛起,即使讀者已讀取新行,因為(可能)它正在等待緩沖區填滿。 理想情況下, readLine()將在讀取新行字符后返回。

我知道我想要的東西是可能的,因為當你使用BufferedReader#readLine()System.in讀取時,它不會在返回之前等待緩沖區填滿。

import java.io.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Example {

    private static final class MyInputStream extends InputStream {

        public final BlockingQueue<String> lines = new LinkedBlockingQueue<>();
        private InputStream current = null;

        @Override
        public int read() throws IOException {
            try {
                if(current == null || current.available() == 0)
                    current = new ByteArrayInputStream(lines.take().getBytes("UTF-8"));
                return current.read();
            }
            catch(InterruptedException ex) {
                return -1;
            }
        }       
    }

    public static void main(String[] args) throws Exception {
        MyInputStream myin = new MyInputStream();
        myin.lines.offer("a line\n");
        BufferedReader in = new BufferedReader(new InputStreamReader(myin));
        System.out.println(in.readLine());
    }
}

此外,如果有更好的方法將字符串發送到InputStream,我願意接受建議。

接受的解決方案:

根據Sotirios Delimanolis對他的解決方案的評論之一的建議,我將改為使用PipedInputStream 我已將它耦合到PipedOutputStream ,並且只要在發送包含新行字符的字符串后調用PipedOutputStream#flush() BufferedReader#readLine()BufferedReader#readLine()就會立即返回。

在更新問題之后,讓新的行字符之后讓BufferedReader停止讀取的唯一方法是將緩沖區大小設置為1 ,這樣就完全不需要BufferedReader

你必須編寫自己的實現。


BufferedReader讀取的字節數多於所需的字節數。 在您的情況下,這意味着它將比新行字符讀取更多。 例如,對於Oracle JVM,它將嘗試讀取8192個字節。 通過你的繼承層次結構,這個

System.out.println(in.readLine());

將嘗試調用read()方法8192次。

前6個調用將返回一個值,一個用於String的字節數組中的每個字符。 下一個,將會看到

if(current == null || current.available() == 0)
     current = new ByteArrayInputStream(lines.take().getBytes("UTF-8"));

而且current.available()將返回0,因為ByteArrayInputStream已被完全消耗。 然后,它會嘗試takeBlockingQueue和無限期地阻塞。

此外,如果有更好的方法將字符串發送到InputStream,我願意接受建議。

好吧,您可以嘗試使用BufferedReader而不是InputStream ,其內容如下所示:

public int read(String directory) throws Exception{
    String line = "";
    File file = new File(directory);
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);

    do{
        lines.add(br.readLine());
    while(br.readLine() != null);

    br.close();

    return Integer.parseInt(line);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM