命令行參數項目實戰
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+"http://"+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+"http://"+deFileName);
if(file.exists()) {
try {
file.delete();
}catch(Exception e) {
e.printStackTrace();
}
System.out.println("刪除成功");
}
}
}
3.運行結果
運行結果基本能夠達到功能要求,目前局限性在于只能輸出到特定文件夾中,也就是我自己提前設定好的文件夾,不夠靈活。不過現在初學階段沒必要考慮這么多,等今天再看一下老師寫的過程,就可以更加熟悉文件的操作了。
總結
這個程序雖然總體來說較為容易,但對于我來說,寫起來還是比較費腦筋的。不過現在寫完之后,確實收獲了很多知識。繼續加油吧!