RocketMQ源码解析(二)
目录
string2File(final String str,final String fileName)
继续上一篇文章中对MixAll的分析
/**
* 把字符串转换为文字
* @param str 字符串
* @param fileName 文件名
* @throws IOException
*/
public static void string2File(final String str,final String fileName)throws IOException {
//创建临时文件.tmp
String tmpFile=fileName+".tmp";
string2FileNotSafe(str,tmpFile);
//写入备份文件
String bakFile=fileName+".bak";
String prevContent=file2String(fileName);
if(prevContent!=null){
string2FileNotSafe(prevContent,bakFile);
}
//删除上次临时文件
File file=new File(fileName);
file.delete();
//修改新的临时文件 fileName.tmp to fileName
file=new File(tmpFile);
file.renameTo(new File(fileName));
}
/**
* 字符串转文字不安全的实现
* @param str 字符串
* @param fileName 文件名
* @throws IOException
*/
public static void string2FileNotSafe(final String str,final String fileName) throws IOException{
File file=new File(fileName);
/**
* 判断输入的文件名是否包含路径,如果是个文件名则会在直接在项目根目录下创建一个文件,且会覆盖存在的相同文件
* 如果路径包含路径,则会先创建前面的路径
* Example dir1/test first create directory dir1 in program root directory(relative directory)
* if the path is absolute directory will create directory form root(like E:/test/test.txt)
*/
File fileParent=file.getParentFile();
if(fileParent!=null){
boolean mkdir = fileParent.mkdir();
}
FileWriter fileWriter=null;
try {
fileWriter=new FileWriter(file);
fileWriter.write(str);
}catch (IOException e){
throw e;
}finally {
if(fileWriter!=null){
fileWriter.close();
}
}
}
/**
* 读取文件内容的输出为字符串
* @param fileName 文件名
* @return
*/
public static String file2String(final String fileName){
File file=new File(fileName);
return file2String(file);
}
public static String file2String(final File file){
if(file.exists()){
//获取文件内容长度
char[] data=new char[(int)file.length()];
boolean result=false;
FileReader fileReader=null;
try {
fileReader=new FileReader(file);
int len=fileReader.read(data);
//判断是否完全读取
result = len == data.length;
}catch (IOException e){
e.printStackTrace();
}finally {
//关闭文件阅读器
if(fileReader!=null){
try {
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
if(result){
//装换为字符串输出
return new String(data);
}
}
return null;
}
上下两个是调用的关系,从后缀不难看出创建的一个是tmp(临时文件)bak(备份文件),具体的创建方法则是调用 File类来创建一个文件,FileWriter类来进行写入,这里强调的是,写入不是添加写而是覆盖写,如果想要添加写的时候应当在创建FileWriter的时候调用重载的构造函数,至于具体写的过程
则是调用其他语言完成的。
然后就是file2String,一个重载的方法,为什么这样写而不是写在一起,主要为了对外接口的统一性,以及程序的最小修改化,一旦以后不用File类了只要改两行并且重载新的方法即可,具体流程也在代码注释中进行解释,在每次读取文件判断是否完全读取是一个很好的习惯,避免读取错误的字符串,毕竟这个方法可是和备份文件有关
/**
* Constructs a FileWriter object given a File object. If the second
* argument is <code>true</code>, then bytes will be written to the end
* of the file rather than the beginning.
*
* @param file a File object to write to
* @param append if <code>true</code>, then bytes will be written
* to the end of the file rather than the beginning
* @throws IOException if the file exists but is a directory rather than
* a regular file, does not exist but cannot be created,
* or cannot be opened for any other reason
* @since 1.4
*/
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
当第二个参数为true时即可追加写入,
这样不难看出string2FileNotSafe方法的过程大概就是