J2ME 技术的学习与实践者

[导入]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 阅读(211) 评论(0)  编辑  收藏 所属分类: OpenBaseMovil 资料


只有注册用户登录后才能发表评论。


网站导航: