[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);
	}
}
发布了2 篇原创文章 · 获赞 3 · 访问量 440

猜你喜欢

转载自blog.csdn.net/qq_19646167/article/details/105244086