`
v5qqbrowser
  • 浏览: 356693 次
文章分类
社区版块
存档分类
最新评论

关于读属性文件(properties)的若干问题

 
阅读更多

文件的存储使用的编码格式与文件读取时的格式不一致. 例如, 在java中, 读取文件的默认格式是iso8859-1, 而我们中文存储的时候一般是UTF-8. 所以导致读出来的是乱码,直接抛出如下异常:

Can'tfindresourceforbundlejava.util.PropertyResourceBundle,keyWebImage

所以要想读中文,只有把文件转换为UTF-8的ascii码才可以。


原来在文件读取的时候,读的文件与被读的文件之间的编码会成为问题。JAVA支持的字符编码集是unicode,即System.out.print("/uXXXX")便可以输出在UNICODE里对应的字符,native2ascii做的就是这件事,把每个各种编码的字符转换成unicode中对应的ascii码(以ascii的形式保存unicode文字内容,所以中文乱码)。在iso8859-1中根本没有对应中文的ascii码那么势必无法利用这样的文件保存中文了,所以,只有使用正确的字符集对编码进行解析才可以获得想要的字符。


经历:

开始的时候记事本建立一个属性文件,保存时编码是:UTF-8, 然后就提示上面的异常。

然后打开后在另存为时把编码选为ASCII,同时把源文件覆盖,然后就没有显示上面的异常了,但是中文出现了乱码。

然后:

把String test = rb.getString("IpToolButton");

替换为

String test = new String(rb.getString("IpToolButton").getBytes("ISO-8859-1"), "GBK");

就没有显示乱码了。

然后干脆用native2ascii命令转化unicode编码: native2ascii GlobalElements.properties GlobalElements.txt

转换后的记事本中原来的中文都是乱码,英文还是原样,然后直接把后缀名改成properties,把原来的那个属性文件删除了。然后

程序中就可以直接用String test = rb.getString("IpToolButton"); 而且输出的就是原来的中文。

native2ascii 后面直接两个相同的文件时,并不能把源文件转化成相应编码的目标文件。

ResourceBundle rb = ResourceBundle.getBundle("GlobalElements2");

// String test = new String(rb.getString("IpToolButton").getBytes("ISO-8859-1"), "GBK");

String test = rb.getString("IpToolButton");

Reporter.log(test);

System.out.println(test);

其他就是关于属性文件放在哪里的问题,参考如下英文【以下转载】:

转:解决 java.util.MissingResourceException: Can't find bundle for base name com...config, locale zh_CN 错误

Solve java.util.MissingResourceException: Can't find bundle for base name com...config, locale zh_CN

at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:836)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:805)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:576)

You know java is looking for a properties file in a specific locale. You may be baffled why java keeps complaining it can't find a properties file that is right there. A few things to keep in mind when debugging this type of errors:

  1. These resource properties files are loaded by classloader, similar to java classes. So you need to include them in your runtime classpath.
  2. These resources have fully-qualified-resource-name, similar to a fully-qualified-class-name, excerpt you can't import a resource into your java source file. Why? because its name takes the form of a string.
  3. ResourceBundle.getBundle("config")tells the classloader to load a resource named"config"with default package (that is, no package). It does NOT mean a resource in the current package that has the referencing class.
  4. ResourceBundle.getBundle("com.cheng.scrap.config")tells the classloader to load a resource named"config"with package"com.cheng.scrap."Its fully-qualified-resource-name is"com.cheng.scrap.config"

For instance, you have a project like


C:/ws/netbeans5/scrap>
| build.xml
+---build
| /---classes
| /---com
| /---cheng
| /---scrap
| Scrap.class
|
+---src
| /---com
| /---cheng
| /---scrap
| config.properties
| Scrap.java

For this statement inScrap.java: ResourceBundle config = ResourceBundle.getBundle("config");to work, you will need tocp src/com/cheng/scrap/config.properties build/classes/such thatconfig.propertiesis directly underclasses, and at the same level ascom. Alternatively, you can putconfig.propertiesinto aconfig.jarsuch thatconfig.propertiesis at the root ofconfig.jarwithout any subdirectories, and includeconfig.jarin the classpath.

For this statement inScrap.java: ResourceBundle config = ResourceBundle.getBundle("com.cheng.scrap.config");to work, you will need tocp src/com/cheng/scrap/config.properties build/classes/com/cheng/scrap/such thatconfig.propertiesis directly underclasses/com/cheng/scrap/, and at the same level asscrap. Alternatively, you can putcom/cheng/scrap/config.properties(along with the long subdirectories) into aconfig.jar,and includeconfig.jarin the classpath.

You may be wondering why it is made so confusing? The benefits are two-fold, as I see it:

  1. Location transparency. At runtime, config.properties is NOT a file, it's just a a loadable resource. config.properites may not exist in your project at all, and the person who wrote Scrap.java may have never seen this resource. A URLClassLoader can find it in a network path or URL at runtime. This is especially important for server-side components such as EJB, Servlet, JSP, etc, who are normally not allowed to access file systems. When you ask classloaders for a resource, its physical location becomes irrelevant.
  2. Namespace mechanism. Having a package allows multiple packages to have resources with the same short name without causing conflicts. This is no different from java packages and xml namespaces.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics