2012-11-02 86 views
11

mark()reset()方法是如何一步一步準確工作的(在下面的代碼中)?我試圖寫我自己的例子,但開始拋出錯誤的標記異常或類似的,我不明白什麼是在這個代碼中放置標記和重置方法,因爲我沒有看到與這個或沒有差異。InputStream,mark(),reset()

import java.io.*; 

class BufferedInputStreamDemo { 
    public static void main(String args[]) { 
     String s = "© is a copyright symbol, " 
       + "however &copy isn't.\n"; 
     byte buf[] = s.getBytes(); 

     ByteArrayInputStream in = new ByteArrayInputStream(buf); 
     int c; 
     boolean marked = false; 

     //try_with_resources 
     try (BufferedInputStream f = new BufferedInputStream(in)) { 
      while ((c = f.read()) != -1) { 
       switch (c) { 
        case '&': 
         if (!marked) { 
          f.mark(32); 
          marked = true; 
         } else { 
          marked = false; 
         } 
         break; 
        case ';': 
         if (marked) { 
          marked = false; 
          System.out.print("(c)"); 
         } else 
          System.out.print((char) c); 
         break; 
        case ' ': 
         if (marked) { 
          marked = false; 
          f.reset(); 
          System.out.print("&"); 
         } else 
          System.out.print((char) c); 
         break; 
        default: 
         if (!marked) 
          System.out.print((char) c); 
         break; 
       } 
      } 
     } catch (IOException e) { 
      System.out.println("I/O Error: " + e); 
     } 
    } 
} 
+1

拋出什麼異常?你有沒有堆棧跟蹤?請更具體地談談你的問題。 – Lion

+0

拋出的異常是'I/O錯誤:java.io.IOException:重置爲無效標記',但我寫了另一個示例中拋出異常。主要是我問什麼是標記(32)並重置**在這個例子**中。 – ashur

+0

@ user1165499查看我的答案,瞭解有關此代碼如何工作的細節,以及我懷疑存在的問題,在另一個示例中。 – dan

回答

6

f.mark(32);是達到讀光標已經在&之後,並且標記被設置爲reset以知道在哪裏跳回。因此,當您檢測到缺少;以關閉元素時,您正在手動打印&,並使用reset方法將讀取光標右移(放置標記後的&,使用mark(32)調用)。在下次閱讀時,因爲您的marked變量未設置,它將打印字符。

mark(32)表示如果您的讀取光標將超過32個字符,則自動移除標記。這可能是您的其他代碼中的問題,即觸發錯誤,因爲標記已經失效。

4

見API文檔:

mark(int)

Marks the current position in this input stream. A subsequent call to the reset method repositions this stream at the last marked position so that subsequent reads re-read the same bytes.

The readlimit argument tells this input stream to allow that many bytes to be read before the mark position gets invalidated.

This method simply performs in.mark(readlimit).

reset()

Repositions this stream to the position at the time the mark method was last called on this input stream.

This method simply performs in.reset().

Stream marks are intended to be used in situations where you need to read ahead a little to see what's in the stream. Often this is most easily done by invoking some general parser. If the stream is of the type handled by the parse, it just chugs along happily. If the stream is not of that type, the parser should toss an exception when it fails. If this happens within readlimit bytes, it allows the outer code to reset the stream and try another parser.