自己写的java程序终于不只是整字符串的了,可以在文件上操作了
1.模仿shell的pwd功能–打印当前目录
java有丰富的库可供我们使用,获取当前文件路径的方法也不用自己写
我们在用File实例化对象的时候,可以利用
File file=new File(this.getClass().getResource("").getPath());
这种方法直接赋予file当前绝对路径,java程序运行时会返回.class文件路径
可是this指针的存在将导致该种方法无法在主方法中使用,我们可以借助
System.getProperty("user.dir")
方法获得当前工作路径,java程序运行时会返回.java文件路径
之后的练习过程中,无法频繁使用this指针方法会使.getAbsolutePath()返回绝对路径的方法使用频率增加,这种方法也需要掌握
下面贴上全部源码
package ezshell;//包名
import java.io.File;
public class pwd {
public void getpath() {
File file=new File(this.getClass().getResource("").getPath());
System.out.println("当前绝对路径"+file.getAbsolutePath());
}
public static void main(String[] args){
// TODO Auto-generated method stub
pwd p=new pwd();
System.out.println("当前工作路径"+System.getProperty("user.dir"));
p.getpath();
}
}
这是运行结果
2.模仿shell的ls功能–打印当前目录下的所有文件
先贴上全部源码镇博客
package ezshell;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;
public class ls {
public static void printlist(List <String> list) {//list输出方法
for(String str:list) {
System.out.println(str);
}
}
public List<String> dirListrec(String dir){//递归
List<String> list=new LinkedList<String>();
File file=new File(dir);
list.add(file.getAbsolutePath());
File[] listfile1=file.listFiles();
if(listfile1!=null&&listfile1.length!=0)
{
for(File f:listfile1) {
if(f.isDirectory()) {
List<String> dirListrec=dirListrec(f.getAbsolutePath());
list.addAll(dirListrec);
continue;
}
list.add(f.getAbsolutePath());
}
}
return list;
}
public List<String> dirListsta(String dir){//栈
List<String> list=new LinkedList<String>();
Stack<File> stack=new Stack<File>();
File file=new File(dir);
list.add(file.getAbsolutePath());
stack.push(file);
//list.add(file.getAbsolutePath());
while(!stack.empty()) {
File popfile=stack.pop();
File[] listfile2=popfile.listFiles();
if(listfile2==null||listfile2.length==0) continue;
for(File f:listfile2) {
if(f.isDirectory()) {
stack.push(f);
}
list.add(f.getAbsolutePath());
}
}
return list;
}
public List<String> dirListque(String dir){//队列
List<String> list=new LinkedList<String>();
Queue<File> queue=new LinkedBlockingQueue<File>();
File file=new File(dir);
list.add(file.getAbsolutePath());
queue.add(file);
while(!queue.isEmpty()) {
File outfile=queue.remove();
File[] listfile3=outfile.listFiles();
if(listfile3==null||listfile3.length==0) continue;
for(File f:listfile3) {
if(f.isDirectory()) {
queue.add(f);
}
list.add(f.getAbsolutePath());
}
}
return list;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ls l=new ls();
String dir=System.getProperty("user.dir");
List<String> reclist=l.dirListrec(dir);
List<String> stalist=l.dirListsta(dir);
List<String> quelist=l.dirListque(dir);
//System.out.println("递归搜索打印当前目录下所有文件");
//printlist(reclist);
//System.out.println("栈搜索打印当前目录下所有文件");
//printlist(stalist);
System.out.println("队列搜索打印当前目录下所有文件");
printlist(quelist);
}
}
然后我们再慢慢看
---------------------------------------------------------------递归法---------------------------------------------------------------------
因为要打印出所有文件,我们不难想到文件夹里面的文件夹也需要我们进去搜索,这种想法很容易让我们想到递归
先打印一个文件夹下的文件,如果发现一个文件夹,那么就将方法在那个文件夹里再走一遍
如何保存数据呢?因为写C写多了第一反映是数组可丰富的java类连HashMap都有有没有在存储无关联数据上比数组方便一些的类呢?List就是我们要寻找的类
那我们的思路就基本确定了,用递归的方法去搜索,再用集合收集数据并输出
那我们需要写一个递归方法,让这个方法返回一个集合,最终输出集合
为了输出美观一点,我们先写个输出方法来保证集合换行输出
public static void printlist(List <String> list) {//list输出方法
for(String str:list) {
System.out.println(str);
}
我们结合集合写递归算法
首先当我们的file文件指向正确时要先把file文件夹绝对路径储存在集合list中
list.add(filePath);
此方法得到了使用,此方法可以在集合list中加入一个filePath元素,测试一下,成功后我们以后就可以按照这个模板写代码了
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;
public List<String> dirListrec(String dir){//递归
List<String> list=new LinkedList<String>();
File file=new File(dir);
list.add(file.getAbsolutePath());
File[] listfile1=file.listFiles();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ls l=new ls();
String dir=System.getProperty("user.dir");
List<String> reclist=l.dirListrec(dir);
System.out.println("递归搜索打印当前目录下所有文件");
printlist(reclist);
可以正常输出后我们去完善递归方法,当集合list储存下当前目录后,需要我们遍历其他文件,由于file指向的是最最外面的文件夹,所以我们需要实例化一个集合listfile1装下file文件里面的其他文件,利用for循环对listfile1进行遍历,我们就完成了file里面一层文件目录的收集,此时代码如下
public List<String> dirListrec(String dir){//递归
List<String> list=new LinkedList<String>();
File file=new File(dir);
list.add(file.getAbsolutePath());
File[] listfile1=file.listFiles();
if(listfile1!=null&&listfile1.length!=0)
{
for(File f:listfile1) {
list.add(f.getAbsolutePath());
}
}
可是如果里面还有文件夹呢?再来一个遍历?可以
可是如果里面的里面还有文件夹呢?手写多层嵌套循环是很不现实的事,所以我们要用到方法递归了
判断file是不是文件夹的方法
if(file.isDirectory())
我们要把这个方法嵌套到我们的for循环里面去,以保证在llistfile1的遍历过程中,如果再次遇到了文件夹,就以该文件夹为形参,调用递归方法,递归结束后我们将集合dirListrec中保存的所有路径合并到list中,这里使用到了
list.addAll(dirListrec)
集合合并方法,这时我们的递归方法就完成了,跑一下程序试一下
public List<String> dirListrec(String dir){//递归
List<String> list=new LinkedList<String>();
File file=new File(dir);
list.add(file.getAbsolutePath());
File[] listfile1=file.listFiles();
if(listfile1!=null&&listfile1.length!=0)
{
for(File f:listfile1) {
if(f.isDirectory()) {
List<String> dirListrec=dirListrec(f.getAbsolutePath());
list.addAll(dirListrec);
continue;
}
list.add(f.getAbsolutePath());
}
}
return list;
}
我没有一个一个数程序个数确定是不是真正全部打印出来啊不过应该是没问题了,如果有问题请指正啊
--------------------------------------------------------------栈方法--------------------------------------------------------------------------
当我们掌握整体思想后,使用其他方法理解起来就并不难了,我们尝试利用栈的方法完成题目要求,毕竟递归与栈都有明确的顺序前后关系,方法几乎一模一样
我们遵循一个原则
出栈存到集合中,遇到文件夹就进栈,栈不空不停
相对于递归方法,栈的使用略微简化了思路,代码量几乎没有得到简化
PS:此时想找个可以看内存使用的工具结果折腾老半天没弄成,成功了后比较下内存使用和时间使用再更新博客
public List<String> dirListsta(String dir){//栈
List<String> list=new LinkedList<String>();
Stack<File> stack=new Stack<File>();
File file=new File(dir);
list.add(file.getAbsolutePath());
stack.push(file);
//list.add(file.getAbsolutePath());
while(!stack.empty()) {
File popfile=stack.pop();
File[] listfile2=popfile.listFiles();
if(listfile2==null||listfile2.length==0) continue;
for(File f:listfile2) {
if(f.isDirectory()) {
stack.push(f);
}
list.add(f.getAbsolutePath());
}
}
return list;
}
记得写主方法啊
---------------------------------------------------------------队列-------------------------------------------------------------------------
不多说了直接上源码,思路一致
public List<String> dirListque(String dir){//队列
List<String> list=new LinkedList<String>();
Queue<File> queue=new LinkedBlockingQueue<File>();
File file=new File(dir);
list.add(file.getAbsolutePath());
queue.add(file);
while(!queue.isEmpty()) {
File outfile=queue.remove();
File[] listfile3=outfile.listFiles();
if(listfile3==null||listfile3.length==0) continue;
for(File f:listfile3) {
if(f.isDirectory()) {
queue.add(f);
}
list.add(f.getAbsolutePath());
}
}
return list;
}
三种方法均可以完成目录下所有文件的打印
3.模仿shell的cat功能
打印一个文件的内容,我们以前写过grep的java实现,所以我们可以直接搬过来,想个办法从控制台输入绝对路径就可以了
PS:有个朋友在实现grep语句时直接利用相对路径完成了当前目录下文件的查找,很方便,不用找绝对路径了,这里记下
控制台吸收整行字符串为绝对路径,别的照抄grep
package ezshell;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class cat {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println("请输入你需要打印内容的文件路径:");
Scanner sc=new Scanner(System.in);
String str1=sc.nextLine();
File dir=new File(str1);
BufferedReader buf=new BufferedReader(new FileReader(dir));
String strs=null;
while((strs=buf.readLine())!=null) {
System.out.println(strs);
}
sc.close();
buf.close();
}
}
让我们输入路径
回车运行
4.模仿shell的mkdir
package ezshell;
import java.io.File;
import java.util.Scanner;
public class mkdir {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入创建文件的完整路径:");
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
File file=new File(str);
sc.close();
file.mkdir();
}
}
5.模仿shell的cp功能
我这个代码是将file里面的内容复制到copy中,这是新建的file
新建的file和copy
java的复制方法有很多中,这里只使用了最为常用的一种方法,使用channel类帮助转化
重点方法
outputchan.transferFrom(inputchan, 0, inputchan.size());
该方法的作用是将inputchan从0位置开始复制inputchan.size()长度到outputchan,此特殊情况为全部复制
其他就是频繁的实例化了,代码如下
package ezshell;
import java.io.*;
import java.nio.channels.FileChannel;
public class cp {
@SuppressWarnings("resource")
public static void copy(File source,File dest) throws IOException{
FileChannel inputchan=null;
FileChannel outputchan=null;
try {
inputchan=new FileInputStream(source).getChannel();
outputchan=new FileOutputStream(dest).getChannel();
outputchan.transferFrom(inputchan, 0, inputchan.size());
}
finally {
inputchan.close();
outputchan.close();
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file=new File("/home/victor/eclipse-workspace/ezshell/file");
File copyfile=new File("/home/victor/eclipse-workspace/ezshell/copy");
copy(file,copyfile);
}
}
代码运行后
完成任务啦
2019-08-05