最近在回头看Java IO的源码,就想着可不可以用java实现一个替换文件中字符串的方法,就像Linux的sed命令那样。在决定做之前,先到网上找了一些资料,可是发现大多数的实现都是把文件的全部内容都load到内存里面,然后调用String的字符替换方法。感觉很不靠谱就是了。于是就动手写了下面这个小demo。
Java的输入输出流做不到随机存取,因此实现的时候,就把替换过字符串的文件输出到了另一个文件里面了(严格来讲,不是替换字符串,而是替换匹配到的字节)。如果要对同一个文件做替换,同学们可以也许用RandomAccessFile,而不是Java 流。
实现类有个缓存buf,内存里面最多存放buf.length个字节,以进行替换操作,因此在把原字符串替换成新字符串的时候,原字符串的长度不能超过buf.length。
直接上代码:
public class MyFileModifier {
private MyFileReader reader = null;
private MyFileWriter writer = null;
private byte[] buf = null;
private static final int DEFAULT_BUFFER_SIZE = 8192;
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
public MyFileModifier(String path,String newFilePath) throws FileNotFoundException {
// 默认的输入输出流形式
this.reader = new MyFileReader(new FileInputStream(path));
this.writer = new MyFileWriter(new FileOutputStream(newFilePath,true));
buf = new byte[DEFAULT_BUFFER_SIZE];
}
public MyFileModifier(String path,String newFilePath,int bufSize) throws FileNotFoundException {
// 默认的输入输出流形式
this.reader = new MyFileReader(new BufferedInputStream(new FileInputStream(path)));
this.writer = new MyFileWriter(new BufferedOutputStream(new FileOutputStream(newFilePath)));
buf = new byte[Math.min(MAX_BUFFER_SIZE,bufSize)];
}
//将文件中所有匹配到的字节替换
public int replaceAll(byte[] content,byte[] newContent) throws IOException {
int cLength = content.length;
if(cLength > buf.length){
throw new IndexOutOfBoundsException("Content too large!");
}
if(reader.available()<=0){
return 0;
}
byte[] buf0 = new byte[cLength-1];
int replaceCount = 0;
int rc = reader.read(buf);
while(true) {
int i;
for(i = 0;i<rc-cLength+1;i++) {
int matchLength = 0;
for (int m = 0; m < cLength; m++) {
if (buf[i+m] != content[m]) {
break;
}
matchLength ++;
}
if(matchLength == cLength){
writer.write(newContent);
i += cLength-1;
replaceCount ++ ;
continue;
}
writer.write(buf[i]);
}
writer.flush();
if(reader.available()>0) {
System.arraycopy(buf, i, buf0, 0, rc-i);
System.arraycopy(buf0, 0, buf, 0, rc-i);
rc = reader.read(buf,rc-i,buf.length-rc+i) + rc - i;
}else {
for(;i<rc;i++){
writer.write(buf[i]);
}
writer.flush();
break;
}
}
return replaceCount;
}
public static void main(String args[]) throws FileNotFoundException {
MyFileModifier myFileModifier = new MyFileModifier("test.properties","myfile.txt",10);
if(myFileModifier == null){
System.out.println("文件未找到");
System.exit(1);
}
try {
int c = myFileModifier.replaceAll(new String("行").getBytes("UTF-8"),new String("哈哈哈哈").getBytes("UTF-8"));
System.out.println(c);
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果有疑问或建议,欢迎大家与我交流。