命令行参数项目实战
1.功能描述
①在终端输入ls,会列出所有文件。并在后面跟上它的大小。比如
Applications 2M
②终端输入mkdir temp就会创建一个temp目录
③终端输入createNewFile temp就会创建一个temp文件
④cope 1.txt 2.txt就是在当前文件夹下复制1.txt到当前文件夹下,并命名为2.txt。这是文件,当然也有可能是拷贝文件夹,在拷贝文件夹的时候,要把里面所有文件都拷贝过去
⑤delete 1.txt就是删除文件1.txt
2.初试
1.遇到的问题
在第一次写的时候,遇到了很多问题
1.1如何接收整行数据
当时我只知道直接用scanner.next()的话,空格或者换行符之后的数据就接收不到了,而功能描述里面,比如mkdir temp,mkdir和temp之间是有空格的,那temp这个数据怎么接收呢?当时也是查了好久,问了好久,才找到了解决办法
①使用.nextLine();,这样会接收一整行数据,当然包括空格之后的。
②接收一整行数据之后,调用String的split(" ")方法,把这一整行数据通过空格分成若干部分,并用字符串数组接收。具体使用示例如下
//接收命令
Scanner scanner = new Scanner(System.in);
String command = scanner.nextLine();
//把输入字符串通过空格隔开
String[] everyName = command.split(" ");
1.2如何列出文件名及大小
当时尝试了很多方法,先想出了第一种解决办法,就是用file.list()方法,并用字符串数组接收,然后一个一个输出名字和用.length()方法得出文件大小。但是今早我才意识到这是不对的。file.list()返回值是String数组,得到的文件或目录名确实是对的,但是用length()方法得出来的不是文件的大小,而是字符串长度。 今早我改过来了,应该
①使用.listFile()方法,返回文件数组,。
②再用每一个文件相应的方法输出姓名和文件大小。具体使用示例如下
//2.保存所有文件名
File[] allFiles = file.listFiles();//注意这里返回的是数组String[]而不是String。
//3.输出文件名(记住要用for循环,不能直接System.out.println(allFiles),这样会直接输出内存地址(没有重写toString)
for(File oneFile:allFiles) {
System.out.print(oneFile.getName());
//double sizeofFile = oneFile.length()/1024;//由于桌面上的文件都很小,所以这里就不需要进行转换了
System.out.println("的大小为"+oneFile.length()+"B");
}
这样输出的结果就类似于
1.3如何复制目录
文件复制较为容易,但是目录就不一样了。
我想到的解决办法就是
①先把文件复制方法写出来
②利用增强for循环,把待复制目录的文件一个一个地取出
③分别把每一个取出的文件进行复制。
大概如下
String[] fileNames = srcFile.list();
for(String oneFile:fileNames) {
}
1.4文件对象的输出
比如oneFile是一个File类型的对象,然后直接输出它,和输出oneFile.getAbsolutePath()得到的结果是一样的。都是文件地址。输出结果类似C:\Users\刘金豪\Desktop.vs。究其原因,应该是没有重写toString方法。
2.初试成果
①Main类
package filetest;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
//接收命令
Scanner scanner = new Scanner(System.in);
String command = scanner.nextLine();
//把输入字符串通过空格隔开
String[] everyName = command.split(" ");
//创建路径
String src = "C:\\Users\\刘金豪\\Desktop";
String des = "C:\\Users\\刘金豪\\Desktop\\copy";
//匹配功能
//输出所有文件
if(everyName[0].equals("ls")) {
listAll.show(src);
}
//创建目录
if(everyName[0].equals("mkdir")) {
//1.保存目录名
String dirName = everyName[1];
//2.创建目录
File file = new File(src+"\\"+dirName);//注意这里是src而不是“src”
if(!file.exists()) {
try{
file.mkdir();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("创建成功");
}
}
//创建文件
if(everyName[0].equals("createNewFile")) {
//1.保存文件名
String fileName = everyName[1];
//2.创建文件
File file = new File(src+"\\"+fileName);
if(!file.exists()) {
try {
file.createNewFile();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("创建成功");
}
}
//copy文件
if(everyName[0].equals("copy")) {
//1.保存文件名称
String src_file = everyName[1];
String des_file = everyName[2];
//2.保存文件路径名
String srcF = src+"\\"+src_file;
String desF = des;//+"\\"+des_file;
//2.创建文件
File srcFile = new File(srcF);
if(srcFile.exists()) {
//如果是文件,则执行这个
if(srcFile.isFile()) {
while(true) {
//判断是字节流还是字符流
System.out.println("请选择字节流或字符流(分别输入1/2)");
Scanner scanner1 = new Scanner(System.in);
int byte_or_char = scanner.nextInt();
if(1 == byte_or_char) {
copyFile.copyByte(srcF, desF);
break;
}if(2 == byte_or_char) {
copyFile.copyChar(srcF, desF);
break;
}else {
System.out.println("输入有误,请重新输入");
continue;
}
}
}else {
String[] fileNames = srcFile.list();
for(String oneFile:fileNames) {
System.out.println("当前文件名为"+oneFile);
while(true) {
//判断是字节流还是字符流
System.out.println("请选择字节流或字符流(分别输入1/2)");
Scanner scanner1 = new Scanner(System.in);
int byte_or_char = scanner.nextInt();
if(1 == byte_or_char) {
copyFile.copyByte(srcF+"\\"+oneFile, desF+"\\"+oneFile);
break;
}if(2 == byte_or_char) {
copyFile.copyChar(srcF+"\\"+oneFile, desF+"\\"+oneFile);
break;
}else {
System.out.println("输入有误,请重新输入");
continue;
}
}
}
}
}
}
//删除文件
if(everyName[0].equals("delete")) {
//保存待删除的文件名
String deFileName = everyName[1];
//创建file
File file = new File(src+"//"+deFileName);
if(file.exists()) {
try {
file.delete();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("删除成功");
}
}
}
}
②listAll类
package filetest;
import java.io.File;
//列出所有文件夹
public class listAll {
public static void show(String src) {
//1.创建文件
File file = new File(src);
//2.保存所有文件名
File[] allFiles = file.listFiles();//注意这里返回的是数组String[]而不是String。
//3.输出文件名(记住要用for循环,不能直接System.out.println(allFiles),这样会直接输出内存地址(没有重写toString)
for(File oneFile:allFiles) {
System.out.print(oneFile.getName());
//double sizeofFile = oneFile.length()/1024;//由于桌面上的文件都很小,所以这里就不需要进行转换了
System.out.println("的大小为"+oneFile.length()+"B");
}
//下面这种会输出类似C:\Users\刘金豪\Desktop\.vs的大小为4096B,是直接输出路径了,我们不需要这种形式,就选择上面那种
/* //2.保存该目录下的所有文件
File[] files = file.listFiles();
//3.逐一输出文件名及大小
for(File oneFile:files) {
System.out.println(oneFile+"的大小为"+oneFile.length()+"B");
//System.out.println(oneFile.getAbsolutePath());//与上面一行代码是一样的,除了后面加的文字叙述“的大小为”后面的。
//也就是说直接输出oneFile和输出oneFile.getAbsolutePath()的结果是一样的。
}*/
}
}
copyFile类
package filetest;
import java.io.*;
//拷贝文件
public class copyFile {
public static void copyByte(String srcF,String desF) {
try( FileInputStream fis = new FileInputStream(srcF);
FileOutputStream fos = new FileOutputStream(desF);) {
int len = 0;
byte[] bytes = new byte[1024];//这一行代码当时不会写了
if((len = fis.read()) != -1) {
fis.read(bytes);
//写入数据
fos.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("复制成功!");
}
public static void copyChar(String srcF,String desF) {
try( FileReader fis = new FileReader(srcF);
FileWriter fos = new FileWriter(desF);) {
int len = 0;
char[] chars = new char[1024];//这一行代码当时不会写了
if((len = fis.read()) != -1) {
fis.read(chars);
//写入数据
fos.write(chars);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("复制成功!");
}
}
三.卷土重来
上面的代码是第一次写完之后的,但是仔细观察,上面的代码结构不行,过程也不是很清晰,总之还是太受c语言的束缚,所以在今早我又改了一下,以更加熟悉“面向对象”的思想
1.项目层级
名称对应的功能都显而易见了
2.具体代码
①Main类
package filetest;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
//接收命令
Scanner scanner = new Scanner(System.in);
String command = scanner.nextLine();
//把输入字符串通过空格隔开(这个是当时没想到的,后来通过反复查询才找到这个知识点。
String[] everyName = command.split(" ");
//创建路径
String src = "C:\\Users\\刘金豪\\Desktop";
String des = "C:\\Users\\刘金豪\\Desktop\\copy";
//匹配功能
matchFunction.mFunction(src,des,everyName);
}
}
②matchFunction类
package filetest;
public class matchFunction {
public static void mFunction(String src,String des,String[] everyName) {
//匹配功能
//输出所有文件
if(everyName[0].equals("ls")) {
listAll.show(src);
}
//创建目录
if(everyName[0].equals("mkdir")) {
mkdir.mkDirectory(src,everyName[1]);
}
//创建文件
if(everyName[0].equals("createNewFile")) {
createFile.cFile(src, everyName[1]);
}
//copy文件
if(everyName[0].equals("copy")) {
copyFile.copy(src, des, everyName[1], everyName[2]);
}
//删除文件
if(everyName[0].equals("delete")) {
deleteFile.deFile(src, everyName[1]);
}
}
}
③listAll类
package filetest;
import java.io.File;
//列出所有文件夹
public class listAll {
public static void show(String src) {
//1.创建文件
File file = new File(src);
//2.保存所有文件名
File[] allFiles = file.listFiles();//注意这里返回的是数组String[]而不是String。
//3.输出文件名(记住要用for循环,不能直接System.out.println(allFiles),这样会直接输出内存地址(没有重写toString)
for(File oneFile:allFiles) {
System.out.print(oneFile.getName());
//double sizeofFile = oneFile.length()/1024;//由于桌面上的文件都很小,所以这里就不需要进行转换了
System.out.println("的大小为"+oneFile.length()+"B");
}
//下面这种会输出类似C:\Users\刘金豪\Desktop\.vs的大小为4096B,是直接输出路径了,我们不需要这种形式,就选择上面那种
/* //2.保存该目录下的所有文件
File[] files = file.listFiles();
//3.逐一输出文件名及大小
for(File oneFile:files) {
System.out.println(oneFile+"的大小为"+oneFile.length()+"B");
//System.out.println(oneFile.getAbsolutePath());//与上面一行代码是一样的,除了后面加的文字叙述“的大小为”后面的。
//也就是说直接输出oneFile和输出oneFile.getAbsolutePath()的结果是一样的。
}*/
}
}
④mkdir类
package filetest;
import java.io.File;
//创建目录
public class mkdir {
public static void mkDirectory(String src,String dirName) {
//创建目录
File file = new File(src+"\\"+dirName);//注意这里是src而不是“src”
if(!file.exists()) {
try{
file.mkdir();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("创建成功");
}
}
}
⑤createFile类
package filetest;
import java.io.File;
public class createFile {
public static void cFile(String src,String fileName) {
//创建文件
File file = new File(src+"\\"+fileName);
if(!file.exists()) {
try {
file.createNewFile();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("创建成功");
}
}
}
⑥copyFile类
package filetest;
import java.io.*;
import java.util.Scanner;
//拷贝文件
public class copyFile {
public static void copy(String src,String des,String src_file,String des_file) {
//保存文件路径名
String srcF = src+"\\"+src_file;
String desF = des;//+"\\"+des_file;
//创建文件
File srcFile = new File(srcF);
if(srcFile.exists()) {
//如果是文件,则执行这个
if(srcFile.isFile()) {
while(true) {
//判断是字节流还是字符流
System.out.println("请选择字节流或字符流(分别输入1/2)");
Scanner scanner1 = new Scanner(System.in);
int byte_or_char = scanner1.nextInt();
if(1 == byte_or_char) {
copyFile.copyByte(srcF, desF);
break;
}if(2 == byte_or_char) {
copyFile.copyChar(srcF, desF);
break;
}else {
System.out.println("输入有误,请重新输入");
continue;
}
}
}else {
String[] fileNames = srcFile.list();
for(String oneFile:fileNames) {
System.out.println("当前文件名为"+oneFile);
while(true) {
//判断是字节流还是字符流
System.out.println("请选择字节流或字符流(分别输入1/2)");
Scanner scanner1 = new Scanner(System.in);
int byte_or_char = scanner1.nextInt();
if(1 == byte_or_char) {
copyFile.copyByte(srcF+"\\"+oneFile, desF+"\\"+oneFile);
break;
}if(2 == byte_or_char) {
copyFile.copyChar(srcF+"\\"+oneFile, desF+"\\"+oneFile);
break;
}else {
System.out.println("输入有误,请重新输入");
continue;
}
}
}
}
}
}
//copy字节文件
public static void copyByte(String srcF,String desF) {
try( FileInputStream fis = new FileInputStream(srcF);
FileOutputStream fos = new FileOutputStream(desF);) {
int len = 0;
byte[] bytes = new byte[1024];//这一行代码当时不会写了
if((len = fis.read()) != -1) {
fis.read(bytes);
//写入数据
fos.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("复制成功!");
}
//copy字符文件
public static void copyChar(String srcF,String desF) {
try( FileReader fis = new FileReader(srcF);
FileWriter fos = new FileWriter(desF);) {
int len = 0;
char[] chars = new char[1024];//这一行代码当时不会写了
if((len = fis.read()) != -1) {
fis.read(chars);
//写入数据
fos.write(chars);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("复制成功!");
}
}
⑦deleteFile 类
package filetest;
import java.io.File;
public class deleteFile {
public static void deFile(String src,String deFileName) {
//创建file
File file = new File(src+"//"+deFileName);
if(file.exists()) {
try {
file.delete();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("删除成功");
}
}
}
3.运行结果
运行结果基本能够达到功能要求,目前局限性在于只能输出到特定文件夹中,也就是我自己提前设定好的文件夹,不够灵活。不过现在初学阶段没必要考虑这么多,等今天再看一下老师写的过程,就可以更加熟悉文件的操作了。
总结
这个程序虽然总体来说较为容易,但对于我来说,写起来还是比较费脑筋的。不过现在写完之后,确实收获了很多知识。继续加油吧!