[導入]OpenBaseMovil StreamParser 流標識符分段器
網站: JavaEye 作者: iwinyeah 鏈接:http://iwinyeah.javaeye.com/blog/170335 發表時間: 2008年03月12日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
在處理資源文件時,我以前的做法是一次性讀入資源文件,然后再進行處理,在處理大文件時,這種方法對由于對機器內存消耗較大而存在隱患,剛想將它改為逐字讀入的方式,在OpenBaseMovil中發現了這個類,很符合我的要求。關鍵代碼如下:
//... 省略 public static final String WHITESPACE = "\r\n\t "; public String next(final String delimiters, final boolean keepWhitespace, final boolean allowComments, final boolean reuseDelimiter, final boolean processEscape) throws IOException { try { final StringBuffer token = new StringBuffer(); startLine = endLine; startChar = endChar; int c = in.read(); endChar++; int status = INITIAL; while (c != -1) { // 若還未讀到文件尾 if (c == '\n') { endLine++; endChar = 0; } switch (status) { case INITIAL: if (delimiters.indexOf(c) > -1) { // 如果是分隔符 lastDelimiter = (char) c; if (isWhiteSpace(c)) { // 如果同時也是空白符并且標識符長度大于零則返回標識符 if (token.length() > 0) { if (reuseDelimiter) { // 如果要重用分隔符則將它推回輸入流中 in.revert((char) c); } return token.toString(); } // 如果還未有數據,還要繼續往下讀 } else { // 如果不是空白符則無論標識符長度是否為零,都要返回 if (reuseDelimiter) { in.revert((char) c); } return token.toString(); } } else if (processEscape && c == '\\') { status = ESCAPE; // 設轉義字符標志 } else if (allowComments && c == '/') { status = COMMENT_START; // 設注釋標志 } else if (isWhiteSpace(c)) { if (keepWhitespace) { // 如果空白符也要用,把它加入標識符中 token.append((char) c); } } else { token.append((char) c); } break; case ESCAPE: // 處理轉義字符 switch (c) { case 'n': token.append('\n'); break; case 'r': token.append('\r'); break; case 't': token.append('\t'); break; case 'b': token.append('\b'); break; case 'f': token.append('\f'); break; default: token.append((char) c); break; } status = INITIAL; // 設正常情況標志 break; case COMMENT_START: // 處理注釋 if (c == '/') { status = LINE_COMMENT; // 是行式注釋 } else if (c == '*') { status = BLOCK_COMMENT; // 是塊式注釋 } else { status = INITIAL; // 如果都不是則把注釋起始符和剛讀入的字符都加入到標識符中 token.append('/').append((char) c); } break; case LINE_COMMENT: if (c == '\n') { status = INITIAL; // 如果當前為行注釋狀態則要一直讀到行尾才恢復正常情況標志 } break; case BLOCK_COMMENT: if (c == '*') { status = COMMENT_END; // 如果當前為塊注釋狀態則要一直讀到*號設為塊注釋結束狀態 } break; case COMMENT_END: if (c == '/') { status = INITIAL; // 在塊結束狀態下讀到/則為塊結束 } else { status = BLOCK_COMMENT; // 否則塊注釋還未結束,恢復為塊注釋狀態 } break; } c = in.read(); // 讀入下一字符 } // 如果讀到文件尾時,標識符長度大于零,則返回標識符,否則返回NULL值 return token.length() > 0 ? token.toString() : null; } catch (IOException e) { throw new IOException("Error reading input L=" + startLine + " C=" + startChar); } } //... 省略
不過從代碼可以看出,它并不支持非Ascii編碼格式的文件,還要進行進一步的改造。
我的計劃是StringBuffer 用byte[]代替,增加setEncode(String encode)方法,返回字符串時使用 new String(byte[], encode)
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:http://iwinyeah.javaeye.com/blog/170335
posted on 2008-03-12 07:03 iwinyeah 閱讀(219) 評論(0) 編輯 收藏 所屬分類: OpenBaseMovil 資料