一、实验项目内容
1、实现文件夹创建、删除、进入。
2、实现当前文件夹下的内容罗列。
3、实现文件拷贝和文件夹拷贝(文件夹拷贝指深度拷贝,包括所有子目录和文件)。
二、实验过程或算法
DocumentManger.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include<stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include<sstream>
#include<iostream>
#include <dirent.h>
#include <fstream>
using namespace std;
class DocumentManager { //DocumentManger 文件管理类
private:
char *path;
char *newpath;
public:
DocumentManager(); //构造函数1
DocumentManager( char *path); //构造函数2
void setNewpath( char* newpath);
void setPath( char* path);
void displayTips(); //命令提示行
int make_dir(const char *path, mode_t mode); //创建文件夹
int change_dir(const char *path); //改变路径
int remove_dir(const char* path); //移除文件夹
int get_file_size_time(const char *filename); //获取文件的信息
DIR * open_dir(const char *path); //打开文件夹
void read_dir(const char *path, bool ListAllFiles); //读取文件夹
int copy_dir(const char *filename, const char *newfilename); //拷贝文件夹
};
#endif
DocumentManager.cpp
#include "DocumentManager.h"
DocumentManager::DocumentManager() {
this->path = NULL;
}
DocumentManager::DocumentManager(char *path) {
this->path = path;
}
void DocumentManager::setNewpath(char* newpath) {
this->newpath = newpath;
}
void DocumentManager::setPath(char* path) { //store this current path
this->path = path;
}
void DocumentManager::displayTips() { //display these tips
cout << "please input commands as the following: " << endl;
cout << "0.mkdir [path]" << endl;
cout << "1.chdir [path]" << endl;
cout << "2.rmdir [path]" << endl;
cout << "3.opendir [path]" << endl;
cout << "4.readdir [path]" << endl;
cout << "5.lldir [path]" << endl;
cout << "5.copy [path] [newPath]" << endl;
cout << "7.exit" << endl;
}
int DocumentManager::make_dir(const char *path, mode_t mode){
if (mkdir(path,mode) != 0) { //make dir with mode
cerr << "make dir fail" << endl;
} else {
cout << "make dir success" << endl;
}
return 0;
}
int DocumentManager::get_file_size_time(const char *filename)
{
struct stat statbuf; //get the informations of file
if (stat(filename, &statbuf) == -1) {
cerr << "Get stat on" << filename << " Error: " << endl;
cerr << strerror(errno) << endl;
}
if (S_ISDIR(statbuf.st_mode)) {
}
if (S_ISREG(statbuf.st_mode)) {
cout << filename << " size:" << statbuf.st_size << " bytes"
<< " modified at " << ctime(&statbuf.st_mtime) << endl;
}
return 0;
}
int DocumentManager::change_dir(const char *path ){ //change the dir
this->path=(char*)path;
if (chdir(path) != 0) {
cout << "change dir fail" << endl;
} else {
cout << "change dir success" << endl;
}
return 0;
}
int DocumentManager::remove_dir(const char* path){ //remove dir
DIR *dirp=opendir(path);
if(dirp==NULL){ //打开文件夹失败
perror(path); //输出错误的原因
return 0;
}
struct dirent *entry;
int ret;
while (1) {
entry = readdir(dirp);
if (entry == NULL) { //若父目录为空,直接退出循环
break;
}
if(strcmp(".",entry->d_name)==0||strcmp("..",entry->d_name)==0){
continue;
}
char buf[80];
snprintf(buf,80,"%s/%s",path,entry->d_name); //重构子目录
ret=remove(buf); //delete these files
if(ret==-1){
if(errno==ENOTEMPTY){ //删除失败
remove_dir(buf);
continue;
}
perror(buf); //输出失败的原因
return 0;
}
}
closedir(dirp);
ret=rmdir(path); //delete the empty dir
if(ret==-1){
perror(path);
}
else{
cout<<"remove dir success!"<<endl;
}
return 0;
}
DIR * DocumentManager::open_dir(const char *path) {
DIR *dirp=opendir(path); //open the dir
if (dirp!= NULL) {
cout << "open dir success" << endl;
}
else{
cerr<<"Open Directory"<<path<<" Error: "<<endl;
cerr<<strerror(errno)<<endl;
}
closedir(dirp); //closedir
return dirp;
}
void DocumentManager::read_dir(const char *path,bool JustListFileName)
{
DIR *dirp=opendir(path);
struct dirent *direntp;
static char dot[] = ".", dotdot[] = "..";
char buf[80];
while ((direntp = readdir(dirp)) != NULL) {
if (strcmp(direntp->d_name, dot) && strcmp(direntp->d_name, dotdot)) {
if (JustListFileName) { //just read the filename
cout << direntp->d_name << endl;
} else {
sprintf(buf, "%s/%s", path, direntp->d_name);
if (get_file_size_time(buf) == -1) //get the information
break;
}
}
}
closedir(dirp); //closedir
}
int DocumentManager::copy_dir(const char *filename, const char *newfilename) {
struct stat cur_file;
stat(filename, &cur_file);
if (S_ISDIR(cur_file.st_mode)) { //路径是文件夹
DIR *cur_dir;
dirent *cur_ent;
int errnum = 0;
if ((cur_dir = opendir(filename)) == NULL){
return 1;
}
if (access(newfilename, F_OK)){ //文件夹不存在,创建这个目标文件夹
errnum |= mkdir(newfilename, S_IRWXU);
}
while ((cur_ent = readdir(cur_dir)) != NULL) //递归,复制子目录
if (strcmp(cur_ent->d_name, ".") && strcmp(cur_ent->d_name, "..")) {
errnum |= copy_dir(((string)filename + "/" + cur_ent->d_name).c_str(),
((string)newfilename + "/" + cur_ent->d_name).c_str());
}
closedir(cur_dir); //close dir
return errnum;
} else { //路径是文件名
if (filename == newfilename){ //若两个路径相同则视为无效,退出
return 0;
}
fstream fsin, fsout; //拷贝文件
fsin.open(filename,ios::in | ios::binary);
fsout.open(newfilename, ios::out |ios::binary);
fsout << fsin.rdbuf();
return 1;
}
}
DocumenManger的测试类:
#include "DocumentManager.h"
#include<stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include<sstream>
#include<iostream>
#include <dirent.h>
#include <fstream>
using namespace std;
int main(){
DocumentManager documentmanger; //declare a DocumentManager
documentmanger.displayTips(); //outputs the tips
string input, command, path, newPath;
int i;
while (getline(cin, input)) {
istringstream is(input);
string s; //deal this inputs
for (i = 0; is >> s; i++) {
if (s.compare("exit") == 0) { //command is exit
exit(0);
}
}
if (i != 2 & i != 3) {
cerr << "your input is Illegal" << endl;
continue;
}
istringstream temp(input);
temp >> command >> path >> newPath;
if (command.compare("mkdir") == 0) { //command is mkdir
const char* pa = path.c_str();
documentmanger.make_dir(pa, 0755);
}
else if (command.compare("chdir") == 0) {//command is chdir
const char* pa = path.c_str();
documentmanger.change_dir(pa);
}
else if (command.compare("rmdir") == 0) {//command is rmdir
const char* pa = path.c_str();
documentmanger.remove_dir((char* )pa);
}
else if (command.compare("opendir") == 0) {//command is opendir
const char* pa = path.c_str();
documentmanger.open_dir((pa));
}
else if (command.compare("readdir") == 0) {//command is readdir
const char* pa = path.c_str();
documentmanger.read_dir(pa,1);
}
else if (command.compare("lldir") == 0) {//command is lldir
const char* pa = path.c_str();
documentmanger.read_dir(pa,0);
}
else if (command.compare("copy") == 0) { //command is copy
const char* pa = path.c_str();
const char* npa = newPath.c_str();
documentmanger.copy_dir(pa, npa);
}
}
return 0;
}