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

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

Can't find resource for bundle java.util.PropertyResourceBundle, key WebImage 

 

所以要想读中文,只有把文件转换为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 in Scrap.java: ResourceBundle config = ResourceBundle.getBundle("config"); to work, you will need to  cp src/com/cheng/scrap/config.properties build/classes/ such that config.properties is directly under classes, and at the same level as com.  Alternatively, you can put config.properties into a config.jar such that config.properties is at the root of config.jar without any subdirectories, and include config.jar in the classpath. 

For this statement in Scrap.java: ResourceBundle config = ResourceBundle.getBundle("com.cheng.scrap.config"); to work, you will need to  cp src/com/cheng/scrap/config.properties build/classes/com/cheng/scrap/ such that config.properties is directly under classes/com/cheng/scrap/, and at the same level as scrap.  Alternatively, you can put com/cheng/scrap/config.properties (along with the long subdirectories) into a config.jarand include config.jar in 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.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值