1. 程式人生 > >替換檔案中某個字串並寫入新內容(Java程式碼實現)

替換檔案中某個字串並寫入新內容(Java程式碼實現)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;

/*
 * 替換檔案(如果該檔案含有子目錄,則包括子目錄所有檔案)中某個字串並寫入新內容(Java程式碼實現).
 * 
 *原理:逐行讀取原始檔的內容,一邊讀取一邊同時寫一個*.tmp的檔案。
 *當讀取的行中發現有需要被替換和改寫的目標內容‘行’時候,用新的內容‘行’替換之。 
 *最終,刪掉原始檔,把*.tmp的檔案重新命名為原始檔名字。
 *
 *注意!程式碼功能是逐行讀取一個字串,然後檢測該字串‘行’中是否含有替換的內容,有則用新的字串‘行’替換原始檔中該處整個字串‘行’。沒有則繼續讀。
 *注意!替換是基於‘行’,逐行逐行的替換!
 *
 * */
public class Modify {

	private String path;
	private final String target;
	private final String newContent;

	public Modify(String path, String target, String newContent) {
		// 操作目錄。從該目錄開始。該檔案目錄下及其所有子目錄的檔案都將被替換。
		this.path = path;
		// target:需要被替換、改寫的內容。
		this.target = target;
		// newContent:需要新寫入的內容。
		this.newContent = newContent;

		operation();
	}

	private void operation() {
		File file = new File(path);
		opeationDirectory(file);
	}

	public void opeationDirectory(File dir) {

		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			File f = files[i];
			if (f.isDirectory())
				// 如果是目錄,則遞迴。
				opeationDirectory(f);
			if (f.isFile())
				operationFile(f);
		}
	}

	public void operationFile(File file) {

		try {
			InputStream is = new FileInputStream(file);
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(is));

			String filename = file.getName();
			// tmpfile為快取檔案,程式碼執行完畢後此檔案將重新命名為原始檔名字。
			File tmpfile = new File(file.getParentFile().getAbsolutePath()
					+ "\\" + filename + ".tmp");

			BufferedWriter writer = new BufferedWriter(new FileWriter(tmpfile));

			boolean flag = false;
			String str = null;
			while (true) {
				str = reader.readLine();

				if (str == null)
					break;

				if (str.contains(target)) {
					writer.write(newContent + "\n");

					flag = true;
				} else
					writer.write(str + "\n");
			}

			is.close();

			writer.flush();
			writer.close();

			if (flag) {
				file.delete();
				tmpfile.renameTo(new File(file.getAbsolutePath()));
			} else
				tmpfile.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		//程式碼測試:假設有一個test資料夾,test資料夾下含有若干檔案或者若干子目錄,子目錄下可能也含有若干檔案或者若干子目錄(意味著可以遞迴操作)。
		//把test目錄下以及所有子目錄下(如果有)中檔案含有"hi"的字串行替換成新的"hello,world!"字串行。
		new Modify(".\\test", "hi", "hello,world!");
	}
}