这里介绍了两种类型的JAVA文件操作,一种是如何将自定义的对象类型数据保存在文件中。另一种是解决多国语言在同一个文件中的保存问题。
如何将自定义的对象类型数据保存在文件中
有些时候,我们不止是要把数据简单地保存在文件中,还希望能把这些数据的相互关系也保存在文件中,这样当从文件重新恢复这些数据的时候,可以很容易地构建出相应的对象,还原之前的关系。
要把自定义类的对象保存在数据文件中,在类定义时一定要实现java.io.Serializable接口。
如下所示,这是一个实现了序列化接口的自定义类的部分代码。这个类名字虽然叫FileInfo,但这并不是一个文件操作的类,在这里我只是把已经读到的一个文件的相关信息保存在这个对象中,比如所读文件的路径,读到的位置,以及其它的信息。接下来才会介绍如何将这种类型的对象保存在文件中。
public class FileInfo implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
int Start; //start position of a file
HashMap<String,String> words; //new words of a file
String filePath;
public FileInfo() { //constructor of the class
super();
Start=0;
words=new HashMap<>();
filePath="";
}
public FileInfo(String inFilePath) { //constructor of the class
super();
Start=0;
words=new HashMap<>();
filePath=inFilePath;
}
public String getFilePath() {
return filePath;
}
下面这个类也实现了java.io.Serializable接口,同时具有文件的读写功能。在这个类中,用一个FileInfo类型的ArrayList来保存对象的信息,用writeDataFile()方法,将这个ArrayList对象写入文件中。而用readDataFile()方法,可以从文件中读取信息,重新恢复到对象列表中。
public class DataFile implements java.io.Serializable {
private String dataFilePath="C:\\EnglishStudy\\dataFile";
public ArrayList<FileInfo> dataFile;
public DataFile() {
super();
readDataFile();
}
public DataFile(ArrayList<FileInfo> dataFile) {
super();
this.dataFile = dataFile;
}
public void writeDataFile() {
try
{
FileOutputStream fileOut =
new FileOutputStream(dataFilePath);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(dataFile);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public void readDataFile() {
try
{
dataFile= new ArrayList<FileInfo>();
File file = new File(dataFilePath);
if(file.exists()){
FileInputStream fileIn = new FileInputStream(dataFilePath);
ObjectInputStream in = new ObjectInputStream(fileIn);
Object tmpObj = in.readObject();
if (tmpObj!=null){
dataFile = (ArrayList<FileInfo>) tmpObj;
}
in.close();
fileIn.close();
}
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("FileInfo list not found");
c.printStackTrace();
return;
}
}
}
下图是将数据从文件读出后,重构自定义类型对象的哈希表,并将数据显示在TextArea的情况
如何在一个文件中保存不同语言的数据
有时需要将多种语言的数据保存在同一文件中,这时不能简单的将字符串或字节数组写入文件,而是在写入数据做编码处理,而读出数据是做解码处理。UTF-8是支持多语言的,所以这里也采用了UTF-8的编解码方式来完成对多语言的处理。
写入多国语言字符串到文件
在下面的代码中展示了写入字符串到文件的方法,这里并不是将传进来的数据直接写到输出流中,而是调用encode()方法,先对字符串做编码处理,将字符串转换为UTF-8的格式,然后再写到输出流中。
public void writeFile(String filePath, String inpuStr) throws IOException {
String data="";
OutputStream outputStream = new FileOutputStream(filePath);
try {
data=encode(inpuStr);
outputStream.write(data.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
outputStream.close();
}
}
编码方法encode()指定了编码的类型为utf-8,这样就确保了多国语言信息都能正确地保留下来。
public static String encode(String input) {
if (input == null) {
return "";
}
try {
return URLEncoder.encode(input, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return input;
}
从文件读出已保存的多国语言字符串
将文件中保存的多国语言字符串重新读出的过程中,包含了一个解码的过程,即将读出的字符串按照UTF-8的格式进行解码。下面的方法中可以看到,当将文件中的数据读出并转换为字符串后,并不能直接使用。因为这个字符串是做过UTF-8编码的字符串,直接使用会显示乱码,因此会调用decode()方法来进行解码。
public String readFile(String filePath) throws IOException {
String data="";
InputStream inputStream = new FileInputStream(filePath);
try {
int count = inputStream.available();
byte[] buf = new byte[count];
int byteRead =inputStream.read(buf, 0,count);
data=decode(new String(buf));
//System.out.println(data);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
inputStream.close();
}
return data;
}
解码方法decode(),按UTF-8的方式对字符串做解码处理,解码后的字符串就可以用来正常显示了。
public static String decode(String input) {
if (input == null) {
return "";
}
try {
return URLDecoder.decode(input, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return input;
}
下图显示的是将多国语言文本从文件中读出并显示在TextArea中的情况。这里的数据的读写直接使用了上文介绍的读写方法。