[14-2] JAVA文件操作實訓之模擬記事本Notepad

本文部分內容引用《JAVA基礎案例教程》-黑馬程序員

第14次-文件操作之字節流和字符流實訓-task02文件操作實訓之模擬記事本-貪吃的釗釗黑。

指導老師:範暢

一、任務描述

編寫一個模擬記事本的程序,通過在控制檯輸入指令,實現在本地新建文件、打開文件和修改文件等功能。
功能:
用戶輸入指令1代表“新建文件"
用戶輸入指令2代表“打開文件”
用戶輸入指令3代表“修改文件”
用戶輸入指令4代表“保存文件"
用戶輸入指令5代表“退出”

二、運行結果

運行結果

三、任務目標

●學會分析“模擬記事本”任務的實現思路
●能夠根據思路獨立完成“模擬記事本”程序的源代碼編寫、編譯及運行。
●掌握利用字符流操作本地文件的方法。

四、實現思路

(1)根據任務介紹和運行結果分析可知,此任務需要創建一個記事本類,在類中可以使用 while循環實現控制檯中操作指令的多次輸入,使用switch語句根據控制檯輸入的操作指令來判 斷執行什麼操作。
(2)輸入指令1時進行新建文件操作,此時需要從控制檯獲取輸入的內容並暫存到全局變量 中,以便後期進行保存和修改內容時使用。可以使用StringBuffer來保存控制檯中每次輸入的內 容,輸入內容時可能會涉及換行,這裏可以使用while循環來循環輸入,每循環一次都將控制檯 獲取的內容拼接換行符後,追加到文本內容中。當內容中輸入“stop"字符串時,輸入文本內容 的操作結束,並將新建文本的內容暫存在全局變量中。
(3)執行指令2時,可以打開指定路徑的文件,由於是模擬記事本程序,因此限定此功能只 支持打開txt文件。此操作首先要獲取輸入的路徑,判斷此路徑的文件是否是txt文件,如果是則 通過字符流讀取此文件,然後將此文件的內容打印至控制檯,並且暫存在全局變量中,將文件的 路徑也保存至全局變量中。
(4)執行指令3時,可以對暫存在全局變量中的文本內容進行修改,修改後的內容也需要暫存到全局變量中。此操作首先要判斷一下修改之 前是否先經過新建文件或者打開文件操作,當確 認經過上述操作後,可以將輸入的字符串與文本內容中目標字符串進行替換,來完成修改內容功 能。修改過程可通過while循環來進行多次的修改,當捕捉到“stop" 字符串時修改結束,並將 修改後的內容暫存到全局變量中。
(5)執行指令4時,將所有全局變量中的內容保存至本地,如果是新建的文件則保存至用戶 輸入的路徑,如果是打開後的文件則將原文件覆蓋。可以通過文件路徑的全局變量判斷是哪種保 存方式,當是打開文件的方式時,直接通過字符流寫入;當是新建的方式時,先獲取用戶輸入的 路徑,再用字符流寫入。
(6)執行指令5,直接退出系統,可以通過代碼“System.exit();" 實現。

五、實現代碼

1、創建記事本類

(1)在主函數中輸出指令說明

public class Notepad {
    public static void main(String[] args) throws Exception {
        System.out.println("--1:新建文件 2:打開文件  3:修改文件  4:保存 5:退出--");
    }
}

(2)通過while循環實現重複輸入,在循環中使用switch語句對應相應的功能。

public class Notepad {
    public static void main(String[] args) throws Exception {
        System.out.println("--1:新建文件 2:打開文件  3:修改文件  4:保存 5:退出--");
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("請輸入操作指令:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    createFile();// 1:新建文件
                    break;
                case 2:
                    openFile();// 2:打開文件
                    break;
                case 3:
                    editFile();// 3:修改文件
                    break;
                case 4:
                    saveFile();// 4:保存
                    break;
                case 5:
                    exit();// 5:退出
                    break;
                default:
                    System.out.println("您輸入的指令錯誤!");
                    break;
            }
        }
    }
}

2、下面我們一一寫出這5個功能的實現代碼。

(1)createFile()

下面寫case 1 新建方法:createFile()
首先定義一個全局變量String message,用來存放文件中的暫存內容,初始爲null。

public class Notepad {
	...
	private static String message = null;//文件中的暫存內容
	...
	}

再通過臨時參數inputMessage將輸入的文字信息一次次地追加、拼接,直到輸入stop,最後再傳遞到message 中。
代碼及詳細註釋如下:

	private static void createFile() {
	        message = "";// 新建文件時,暫存文件內容清空
	        Scanner sc = new Scanner(System.in);
	        System.out.println("請輸入內容,停止編寫請輸入\"stop\":");// 提示
	        StringBuffer stb = new StringBuffer();// 字符緩衝區,用於後期輸入內容的拼接
	        String inputMessage = "";//記錄每一次輸入的內容
	        while (!inputMessage.equals("stop")) {// 當輸入“stop”時,停止輸入
	            if (stb.length() > 0) {
	                stb.append("\r\n");// 追加換行符
	            }
	            stb.append(inputMessage);// 追加,拼接輸入信息
	            inputMessage = sc.nextLine();// 獲取輸入信息
	        }
	        message = stb.toString();// 將輸入內容暫存
	    }

可以看到,這裏我們定義了一個字符緩衝區 stb ,通過while循環我們把inputMessage中的文字內容拼接到stb中,最後再完整地將字符緩衝區 stb中的內容一次性傳遞給message。

(2)saveFile()

新建文件之後,接下來我們寫保存方法,case 4 保存方法:saveFile()
首先定義一個全局變量String filePath,用來存放文件的路徑,初始爲null。

public class Notepad {
	...
	private static String filePath = null;//文件路徑
	...
	}
	private static void saveFile() throws IOException {
	        //待完成操練開始
	        Scanner sc = new Scanner(System.in);
	        FileWriter out = null;
	        if(filePath != null){//文件是由“打開”載入的
	            out = new FileWriter(filePath);//將原文件覆蓋
	        } else {//新建的文件
	            System.out.print("請輸入文件保存的絕對路徑:");
	            String path = sc.next();//獲取文件保存的路徑
	            filePath = path;
	            //將輸入路徑中大寫字母替換成小寫字母后判斷是不是文本格式
	            if (!filePath.toLowerCase().endsWith(".txt")) {
	                filePath +=".txt";
	            }
	            out = new FileWriter(filePath);//構造輸出流
	        }
	        out.write(message);//寫入暫存的內容
	        out.close();//關閉輸出流
	        message = null;//修改文件前先將寫入內容清空
	        filePath = null;//將文件路徑置空
	
	        //待完成操練結束
	    }

第5行代碼根據路徑的全局變量是否爲空,來判斷此時內容的全局變量是新建文件產生的還是打開文件產生的。

如果是打開 文件產生的,則將此文件覆蓋掉;

如果是新建文件產生的,則從獲得控制檯輸入的路徑之後,判斷其是否是.txt,如果不是則將其轉換成.txt。再將message中暫存的內容寫入文本文件。最後將文件路徑filePath 和文件內容message的全局變量置空。

補充:
.toLowerCase()方法
語法:public String toLowerCase()
功能:返回一個字符串,該字符串中的字母被轉換成小寫字母,而且對非字母字符不會產生影響。
與之對應的方法是toUpperCase()方法。

.endsWith()
語法:public boolean endsWith(String suffix)
參數:suffix – 指定的後綴。
功能:如果參數表示的字符序列是此對象表示的字符序列的後綴,則返回 true;否則返回 false。

(3)openFile()

接下來我們寫打開方法,case 2 打開方法:openFile()

	private static void openFile() throws Exception {
			//待完成操練開始
			message = "";//打開文件時,將暫存文件清空
			Scanner sc = new Scanner(System.in);
			System.out.print("請輸入打開文件的位置:");
			filePath = sc.next();//獲取打開文件的路徑
			//判斷打開的文件是否爲.txt文件
			if (filePath != null && !filePath.endsWith(".txt")) {
				System.out.print("請選擇文本!");
				return;
			}
			FileReader in = new FileReader(filePath);//實例化一個FileReader對象
			char[] charArray = new char[1024];//緩存數組
			int len = 0;
			StringBuffer sb = new StringBuffer();
			//循環讀取,一次讀取一個字符數組
			while ((len = in.read(charArray)) != -1) {
				sb.append(charArray);
			}
			message = sb.toString();//將打開文件內容暫存到message以便輸出打印
			System.out.println("打開文件內容:" + "\r\n" + message);
			in.close();
			//待完成操練結束
		}

首先獲取控制檯傳入的文件路徑,並將其存儲到filePath 全局變量中。判斷將要打開的文件的格式是否是.txt。利用字符輸入流讀取文件的內容。將StringBuffer中的內容轉成String 類型,並存 入全局變量message中,以便修改和保存時使用。

(4)editFile()

接下來我們寫修改方法,case 3 修改文件方法:editFile()

	private static void editFile() {
			if (message == "" && filePath == null) {
				System.out.println("請先新建文件或者打開文件");
				return;
			}
			Scanner sc = new Scanner(System.in);
			System.out.println("請輸入要修改的內容(以 \"修改的目標文字:修改之後的文字\" 格式),"
					+ "停止修改請輸入\"stop\":");
			String inputMessage = "";
			while (!inputMessage.equals("stop")) {// 當輸入stop時,停止修改
				inputMessage = sc.nextLine();
				if (inputMessage != null && inputMessage.length() > 0) {
					// 將輸入的文字根據“:”拆分成數組
					String[] editMessage = inputMessage.split(":");
					if (editMessage != null && editMessage.length > 1) {
						// 根據輸入的信息將文件中內容替換
						message = message.replace(editMessage[0], editMessage[1]);
					}
				}
			}
			System.out.println("修改後的內容:" + "\r\n" + message);
		}

使用while 循環實現多次替換文件內容的功能,首先獲取替換的指令,再將 輸入的內容通過英文的冒號:分割出(修改的目標文字,修改之後的文字),傳遞到字符串數組editMessage中,分別對應數組元素(editMessage[0], editMessage[1])。最後將內容的全局變量message進行替換。打印。

補充:
.split
語法:stringObject.split(separator)
參數:separator 字符串或正則表達式,從該參數指定的地方分割 stringObject。
功能:把一個字符串分割成字符串數組。
.replace
語法:stringObject.replace(target,replacement)
參數:target需要被替換的字符,replacement替換後的字符。
功能:在字符串中用一些字符替換另一些字符

(5)exit()

case 5 退出方法:exit()
輸出結束語友好提示,然後調用系統退出方法。

	private static void exit() {
	        System.out.println("您已退出系統,謝謝使用!");
	        System.exit(0);
	    }

六、完整源碼

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

/**
 * 模擬記事本程序
 */
public class Notepad {
	private static String filePath = null;//文件路徑
	private static String message = null;
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		System.out.println("--1:新建文件 2:打開文件  3:修改文件  4:保存 5:退出--");
		while (true) {
			System.out.print("請輸入操作指令:");
			int command = sc.nextInt();
			switch (command) {
				case 1:
					createFile();// 1:新建文件
					break;
				case 2:
					openFile();// 2:打開文件
					break;
				case 3:
					editFile();// 3:修改文件
					break;
				case 4:
					saveFile();// 4:保存
					break;
				case 5:
					exit();// 5:退出
					break;
				default:
					System.out.println("您輸入的指令錯誤!");
					break;
			}
		}
	}
	/**
	 * 新建文件 從控制檯獲取內容
	 */
	private static void createFile() {
		message = "";// 新建文件時,暫存文件內容清空
		Scanner sc = new Scanner(System.in);
		System.out.println("請輸入內容,停止編寫請輸入\"stop\":");// 提示
		StringBuffer stb = new StringBuffer();// 用於後期輸入內容的拼接
		String inputMessage = "";
		while (!inputMessage.equals("stop")) {// 當輸入“stop”時,停止輸入
			if (stb.length() > 0) {
				stb.append("\r\n");// 追加換行符
			}
			stb.append(inputMessage);// 拼接輸入信息
			inputMessage = sc.nextLine();// 獲取輸入信息
		}
		message = stb.toString();// 將輸入內容暫存
	}
	/**
	 * 打開文件
	 */
	private static void openFile() throws Exception {
		//待完成操練開始
		message = "";//打開文件時,將暫存文件清空
		Scanner sc = new Scanner(System.in);
		System.out.print("請輸入打開文件的位置:");
		filePath = sc.next();//獲取打開文件的路徑
		//判斷打開的文件是否爲.txt文件
		if (filePath != null && !filePath.endsWith(".txt")) {
			System.out.print("請選擇文本!");
			return;
		}
		FileReader in = new FileReader(filePath);//實例化一個FileReader對象
		char[] charArray = new char[1024];//緩存數組
		int len = 0;
		StringBuffer sb = new StringBuffer();
		//循環讀取,一次讀取一個字符數組
		while ((len = in.read(charArray)) != -1) {
			sb.append(charArray);
		}
		message = sb.toString();//將打開文件內容暫存到message以便輸出打印
		System.out.println("打開文件內容:" + "\r\n" + message);
		in.close();
		//待完成操練結束
	}
	/**
	 * 修改文件內容 通過字符串替換的形式
	 */
	private static void editFile() {
		if (message == "" && filePath == null) {
			System.out.println("請先新建文件或者打開文件");
			return;
		}
		Scanner sc = new Scanner(System.in);
		System.out.println("請輸入要修改的內容(以 \"修改的目標文字:修改之後的文字\" 格式),"
				+ "停止修改請輸入\"stop\":");
		String inputMessage = "";
		while (!inputMessage.equals("stop")) {// 當輸入stop時,停止修改
			inputMessage = sc.nextLine();
			if (inputMessage != null && inputMessage.length() > 0) {
				// 將輸入的文字根據“:”拆分成數組
				String[] editMessage = inputMessage.split(":");
				if (editMessage != null && editMessage.length > 1) {
					// 根據輸入的信息將文件中內容替換
					message = message.replace(editMessage[0], editMessage[1]);
				}
			}
		}
		System.out.println("修改後的內容:" + "\r\n" + message);
	}
	/**
	 * 保存 新建文件存在用戶輸入的路徑 打開的文件將原文件覆蓋
	 */
	private static void saveFile() throws IOException {
		//待完成操練開始
		Scanner sc = new Scanner(System.in);
		FileWriter out = null;
		if(filePath != null){//文件是由“打開”載入的
			out = new FileWriter(filePath);//將原文件覆蓋
		} else {//新建的文件
			System.out.print("請輸入文件保存的絕對路徑:");
			String path = sc.next();//獲取文件保存的路徑
			filePath = path;
			//將輸入路徑中大寫字母替換成小寫字母后判斷是不是文本格式
			if (!filePath.toLowerCase().endsWith(".txt")) {
				filePath +=".txt";
			}
			out = new FileWriter(filePath);//構造輸出流
		}
		out.write(message);//寫入暫存的內容
		out.close();//關閉輸出流
		message = "";//修改文件前先將寫入內容清空
		filePath = null;//將文件路徑置空

		//待完成操練結束
	}
	/**
	 * 退出
	 */
	private static void exit() {
		System.out.println("您已退出系統,謝謝使用!");
		System.exit(0);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章