【发布时间】:2021-03-12 11:38:57
【问题描述】:
我想构建仅包含部分键/值的 ResourceBundles 属性文件中的对,从而将大量文件保存为 与将这些部分或部分中的每一个存储在单个文件中相比。 这些部分由以“#”开头的标题行标记并与 由一个空行彼此。下面代码之后的示例属性文件包含两个部分:
- #FileChooser
- #OptionPane
我试图通过传递一个自定义的 ClassLoader 来实现这一点,它只读 所需的部分,在 getBundle(...) 方法中。 CustomClassLoader 工作 很好地减少了键定义,但 ResourceBundle 仍然包含属性文件的所有键。
import java.io.*;
import java.util.*;
public class ResourceReader {
public ResourceReader() {
Locale locale= Locale.getDefault();
ResourceBundle i18n= ResourceBundle.getBundle("ComponentBundle", locale,
new CustomClassLoader("#FileChooser"));
Enumeration<String> enu= i18n.getKeys();
System.out.println("Keys of ResourceBundle");
printEnumeration(enu);
}
public static void main(String args[]) {
new ResourceReader();
}
public void printEnumeration(Enumeration<String> enu) {
int i= 1;
while (enu.hasMoreElements()) {
System.out.println(i+".: "+enu.nextElement());
i++;
}
}
//////////////////////////////////////////////////////////////////////////////
public class CustomClassLoader extends ClassLoader {
String section;
public CustomClassLoader(String section) {
this.section= section;
}
@Override
public Class findClass(String name) throws ClassNotFoundException {
byte[] b = loadClassFromFile(name);
//System.out.writeBytes(b); // OK.
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassFromFile(String fileName) {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
fileName.replace('.', File.separatorChar) + ".properties");
byte[] buffer;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
int nextValue = 0;
try {
while ( (nextValue = inputStream.read()) != -1 ) {
byteStream.write(nextValue);
}
} catch (IOException e) {
e.printStackTrace();
}
buffer = extractSection(byteStream.toString(), section);
return buffer;
}
private byte[] extractSection(String stream, String caption) {
final String LINE_SEP= System.getProperty("line.separator", "\n");
String[] lines= stream.split(LINE_SEP);
// Detect first and last line (exclusive) of section.
int iEnd= 0, iStart= -1;
for (int i=0; i<lines.length; i++) {
lines[i]= lines[i].trim();
if (iStart==-1) {
if (!lines[i].equals(caption)) continue;
iStart= i+1;
i++;
}
else if (lines[i].isEmpty()) {
iEnd= i;
break;
}
}
if (iEnd==0) iEnd= lines.length+1;
StringBuilder sb= new StringBuilder();
for (int i=iStart; i<iEnd; i++)
sb.append(lines[i]+LINE_SEP);
return sb.toString().getBytes();
}
}
}
//////////////////////////////////////////////////////////////////////////////
/* // 文件 ComponentBundle.properties
#FileChooser
acceptAllFileFilterText= All files (*.*)
cancelButtonText= Cancel
cancelButtonToolTipText= Cancel
#OptionPane
Cancel= Cancel
Input= Input
Message= Message
No= No
// End of ComponentBundle.properties
*/
【问题讨论】:
标签: java classloader resourcebundle