用Java IO流替換文件中的字符串


 

  最近在回頭看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();
        }
    }
}
  

  如果有疑問或建議,歡迎大家與我交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM