当前位置: 代码迷 >> J2SE >> j2me 兑现 j2se 的 Properties 功能
  详细解决方案

j2me 兑现 j2se 的 Properties 功能

热度:2072   发布时间:2013-02-25 00:00:00.0
j2me 实现 j2se 的 Properties 功能
我们知道 j2me 中没有 j2se 里边的 Properties 类,要自己实现才能像 j2se 那样读取文件的,现在 j2mepolish 里边的 de.enough.polish.util.Properties 就实现了类似 j2se 的 Properties, 加上de.enough.polish.util.ResourceStreamUtil(旧版本polish 没有这个类,要自己实现相应功能)可以让我们容易读取属性文件。关于 ResourceStreamUtil 类和 Properties 类的介绍大家可以参考 j2mepolish 里边的 api doc。

只要在把你所新建的 .properties 文件放在 resources 文件夹下(相当于一个资源文件,也可以放其他地方,但一定要把它配置成资源),就可以用相应的方法读取, 看下边例子:

test.properties文件:
name=muscle-liusex=maleage=24


读取时的部分代码:
Properties prop = new Properties();InputStream in = null;try{  byte[] sData = ResourceStreamUtil.getResourceAsByteArray("/test.properties");  System.out.println("sData.length:  "+sData.length);  in =  new ByteArrayInputStream(sData);              prop.load(in);}catch (IOException e){  e.printStackTrace();}System.out.println("prop.getProperty(\"name\"): "+prop.getProperty("name"));System.out.println("prop.getProperty(\"sex\"): "+prop.getProperty("sex"));System.out.println("prop.getProperty(\"age\"): "+prop.getProperty("age"));


运行结果如下:
prop.getProperty("name"): muscle-liuprop.getProperty("sex"): maleprop.getProperty("age"): 24


在运用中我发现这个 Properties 类有个 bug,就是不支持 # 的注释(也就是说,属性文件里边除了 key-value 的内容,不能有其他的非 k-v 内容)。下边是我修改 Properties 里边的 load 方法,令它支持 # 注释:
原来的 load 方法:
public void load(InputStream in, String encoding, boolean generateIntegerValues ) throws IOException	{		this.isIntegerValues = generateIntegerValues;		int bufferLength = 2 * 1024;		byte[] buffer = new byte[ bufferLength ];		int read;		int start = 0;		int end = 0;		boolean newLineFound;		while ( (read = in.read(buffer, start, bufferLength - start )) != -1) {			// search for next \r or \n			String line;			if (encoding != null) {				line = new String( buffer, 0, read + start, encoding );			} else {				line = new String( buffer, 0, read + start );							}			start = 0;			newLineFound = true;			while (newLineFound) {				newLineFound = false;				char c = '\n';				for (int i = start; i < line.length(); i++) {					c = line.charAt(i);					if (c == '\r' || c == '\n') {						end = i;						newLineFound = true;						break;					}				}				if (newLineFound) {					int splitPos = line.indexOf('=', start);					if(splitPos == -1) {						throw new IOException("no = separator: " + line.substring( start, end ));					}					String key = line.substring( start, splitPos );					String value = line.substring( splitPos + 1, end );					if (generateIntegerValues) {						try {							put( key, Integer.valueOf(value) );						} catch(NumberFormatException ex) {							throw new IOException( ex.toString() );						}																	} else {						put( key, value );						}					if (c == '\r') {						start = end + 2;					} else {						start = end + 1;					}				}			}			// now all key-value pairs have been read, now move any remaining data to the beginning of the buffer:			if (start < read) {				System.arraycopy( buffer, start, buffer, 0, read - start );				start = read - start;			} else {				start = 0;			}		}	}	



修改后的 load 方法:
public void load(InputStream in, String encoding, boolean generateIntegerValues ) throws IOException	{		this.isIntegerValues = generateIntegerValues;		int bufferLength = 2 * 1024;		byte[] buffer = new byte[ bufferLength ];		int read;		int start = 0;		int end = 0;		boolean newLineFound;		boolean isComment;		while ( (read = in.read(buffer, start, bufferLength - start )) != -1) {			// search for next \r or \n			String line;			if (encoding != null) {				line = new String( buffer, 0, read + start, encoding );			} else {				line = new String( buffer, 0, read + start );							}			start = 0;			newLineFound = true;			while (newLineFound) {				newLineFound = false;				isComment = false;				char c = '\n';				char firstChar = line.charAt(start);				if(firstChar == '#'){					isComment = true;				}				for (int i = start; i < line.length(); i++) {					c = line.charAt(i);										if (c == '\r' || c == '\n') {						end = i;						newLineFound = true;						break;					}				}				if (newLineFound && !isComment) {					int splitPos = line.indexOf('=', start);					if(splitPos == -1) {						throw new IOException("no = separator: " + line.substring( start, end ));					}					String key = line.substring( start, splitPos );					String value = line.substring( splitPos + 1, end );					if (generateIntegerValues) {						try {							put( key, Integer.valueOf(value) );						} catch(NumberFormatException ex) {							throw new IOException( ex.toString() );						}																	} else {						put( key, value );						}				}				if (c == '\r') {					start = end + 2;				} else {					start = end + 1;				}			}			// now all key-value pairs have been read, now move any remaining data to the beginning of the buffer:			if (start < read) {				System.arraycopy( buffer, start, buffer, 0, read - start );				start = read - start;			} else {				start = 0;			}		}	}


这样我们就可以像 j2se 那样写 properties 文件了..当然,如果你的项目中没有用 j2mepolish, 那你也可以借用这两个类到你的工程,照样可以实现 j2se 的 properties 功能
1 楼 mingkg21 2008-04-14  
复杂了一些,还可以简单一点。。。。。
2 楼 jandyguan 2008-07-15  
因为Properties类继承Hashmap,实现接口Externalizable,这些都是Polish的东西,所以在其它项目单用这两个类是不行的。
3 楼 muscle-liu 2008-07-30  
我们可以继承j2me里边的Hashtable来实现的,而接口Externalizable 是继承Serializable的,所以完全可以改为自己的properties,在其他的j2me项目里都能用