2009-10-06 26 views

回答

33

我認爲您在尋找inputstream.available()。它沒有告訴你它是否爲空,但是它可以告訴你數據是否被讀取。

+25

'available()'告訴你是否有數據可以被讀取,它不一定告訴你這個流是否爲空。 – skaffman 2009-10-06 08:37:30

+1

@skaffman:非常感謝!我認爲這是足夠的:)。編輯我的答案以反映它。 – vpram86 2009-10-06 08:40:06

+0

available()沒有完成我所需要的,但它是最接近的解決方案。 – 2009-10-06 11:58:19

48

不,你不能。 InputStream旨在與遠程資源一起使用,因此直到實際讀取它時才能知道它是否在那裏。

但是,您也許可以使用java.io.PushbackInputStream,它允許您從流中讀取數據,看看是否存在某些內容,然後將它「推回」流中(這不是它真正起作用的方式,但這是事實它對客戶端代碼的行爲方式)。

+4

如果你不知道你正在處理什麼樣的流(即你有一個將InputStream作爲參數的方法),PushbackInputStream似乎是最強大的解決方案。 – 2011-08-23 03:52:57

+0

檢查我的答案基於PushbackInputStream的實現:http://stackoverflow.com/a/19137900/82609 – 2013-10-02 13:21:04

+0

正如Android SDK中[InputStream.available()]的文檔中所述(https://developer.android.com/reference/JAVA/IO /的InputStream。html#available())「類InputStream的可用方法總是返回0.這個方法應該被子類覆蓋。」這隱含地告訴你在InputStream實例上調用'available()'方法實際上不會返回任何有意義的東西。 – Eido95 2017-03-14 21:38:18

4

您可以使用available()方法詢問流是否有任何可用的數據在您稱之爲的那一刻。但是,該功能不能保證適用於所有類型的輸入流。這意味着您不能使用available()來確定是否實際阻止對read()的呼叫。

+0

請告訴我一個情況,可用()將無法正常工作。 – 2009-10-07 06:19:41

+4

InputStream的available()方法默認返回0;如果一個子類不覆蓋這個方法,那麼總是返回0。 – 2009-10-07 06:28:28

+0

......我知道它在SSL Socket上不起作用,但這不適用於我。 – 2009-10-07 06:28:34

4

如果InputStream你使用支持標記/復位的支持,你也可以嘗試讀取數據流的第一個字節,然後將其恢復到原來的位置:

input.mark(1); 
final int bytesRead = input.read(new byte[1]); 
input.reset(); 
if (bytesRead != -1) { 
    //stream not empty 
} else { 
    //stream empty 
} 

如果你不這樣做控制您正在使用什麼樣的InputStream,您可以使用markSupported()方法來檢查標記/重置是否可以在數據流上工作,否則返回available()方法或java.io.PushbackInputStream方法。

+0

讀取調用塊直到您輸入,所以根據我的經驗,這將始終表明該流不是空的(除非可能遇到流結束) – dcstraw 2012-02-04 21:57:39

+0

我必須對臨時文件讀取執行此操作,並且它運行良好(我使用'BufferedReader'來確保它支持標記/重置,而不必測試它) – 2014-08-25 13:42:33

+0

這個問題明確指出'不使用read()''方法而不使用'方法'。 – EJP 2014-11-06 09:08:34

0

如何使用inputStreamReader.ready()找出?

import java.io.InputStreamReader; 

/// ... 

InputStreamReader reader = new InputStreamReader(inputStream); 
if (reader.ready()) { 
    // do something 
} 

// ... 
+0

這不適用於所有InputStream子類;特別是,我一直無法讓它爲GZIPInputStream工作。我會冒險猜測它是使用available()實現的,這對GZIPInputStream似乎也不起作用。 – 2011-08-23 03:00:57

+0

問題是關於'InputStream',而不是'Reader'。 – EJP 2014-11-06 09:07:02

9

基於使用PushbackInputStream的建議,你會發現這裏的執行爲例:

/** 
* @author Lorber Sebastien <i>([email protected])</i> 
*/ 
public class NonEmptyInputStream extends FilterInputStream { 

    /** 
    * Once this stream has been created, do not consume the original InputStream 
    * because there will be one missing byte... 
    * @param originalInputStream 
    * @throws IOException 
    * @throws EmptyInputStreamException 
    */ 
    public NonEmptyInputStream(InputStream originalInputStream) throws IOException, EmptyInputStreamException { 
    super(checkStreamIsNotEmpty(originalInputStream)); 
    } 


    /** 
    * Permits to check the InputStream is empty or not 
    * Please note that only the returned InputStream must be consummed. 
    * 
    * see: 
    * http://stackoverflow.com/questions/1524299/how-can-i-check-if-an-inputstream-is-empty-without-reading-from-it 
    * 
    * @param inputStream 
    * @return 
    */ 
    private static InputStream checkStreamIsNotEmpty(InputStream inputStream) throws IOException, EmptyInputStreamException { 
    Preconditions.checkArgument(inputStream != null,"The InputStream is mandatory"); 
    PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); 
    int b; 
    b = pushbackInputStream.read(); 
    if (b == -1) { 
     throw new EmptyInputStreamException("No byte can be read from stream " + inputStream); 
    } 
    pushbackInputStream.unread(b); 
    return pushbackInputStream; 
    } 

    public static class EmptyInputStreamException extends RuntimeException { 
    public EmptyInputStreamException(String message) { 
     super(message); 
    } 
    } 

} 

這裏有一些經過測試:

@Test(expected = EmptyInputStreamException.class) 
    public void test_check_empty_input_stream_raises_exception_for_empty_stream() throws IOException { 
    InputStream emptyStream = new ByteArrayInputStream(new byte[0]); 
    new NonEmptyInputStream(emptyStream); 
    } 

    @Test 
    public void test_check_empty_input_stream_ok_for_non_empty_stream_and_returned_stream_can_be_consummed_fully() throws IOException { 
    String streamContent = "HELLooooô wörld"; 
    InputStream inputStream = IOUtils.toInputStream(streamContent, StandardCharsets.UTF_8); 
    inputStream = new NonEmptyInputStream(inputStream); 
    assertThat(IOUtils.toString(inputStream,StandardCharsets.UTF_8)).isEqualTo(streamContent); 
    } 
+0

這個問題明確指出'不使用'read()''和'沒有讀取'的方法。 – EJP 2014-11-06 09:09:11

+1

@EJP從概念上講,如果你沒有任何關於該流的其他相關信息(例如HTTP流的Content-Size頭),你就不知道流是否爲空而沒有收到某些東西。可以假設提問者明白這一點,並且只是想檢查流空,同時仍然能夠從頭讀取它。 – 2014-11-06 11:27:23

+0

我完全同意,但這是問題中指定的約束,並且他也未響應請求他的'空'的定義。 – EJP 2017-11-08 09:22:42

-1
public void run() { 
    byte[] buffer = new byte[256]; 
    int bytes;      

    while (true) { 
     try { 
      bytes = mmInStream.read(buffer); 
      mHandler.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); 
     } catch (IOException e) { 
      break; 
     } 
    } 
} 
+0

用這個替換run()。 – omer 2015-05-01 11:29:23