如何在c / c ++中将文件从一个目录复制到另一个目录

我正在寻找一个关于如何在C中将文件从一个目录复制到另一个目录的简单示例。该程序应该只使用C本机的跨平台函数。

这是一个简单的未经测试的C程序,可以满足您的需求:

 #include  int main(int argn, char * argv[]) { int src_fd, dst_fd, n, err; unsigned char buffer[4096]; char * src_path, dst_path; // Assume that the program takes two arguments the source path followed // by the destination path. if (argn != 3) { printf("Wrong argument count.\n"); exit(1); } src_path = argv[1]; dst_path = argv[2]; src_fd = open(src_path, O_RDONLY); dst_fd = open(dst_path, O_CREAT | O_WRONLY); while (1) { err = read(src_fd, buffer, 4096); if (err == -1) { printf("Error reading file.\n"); exit(1); } n = err; if (n == 0) break; err = write(dst_fd, buffer, n); if (err == -1) { printf("Error writing to file.\n"); exit(1); } } close(src_fd); close(dst_fd); } 
 open source file read-only create destination file for write while there's still data in source file read data from source file write it to destination file close both files 

我相信你能做到!

下面是使用dirent.h在C ++中复制文件的正确方法。 请注意,dirent.h是Linux的一部分,但不包含在Windows中。 对于Windows,请看这里 。

对于Windows Visual C ++:

  // CopyAll_Windows.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include"dirent.h" //Copy dirent.h to folder where stdafx.h is and add to project #include #include #include  #define MAX 1024 #define MAX_FILE_NAME_LEN 256 using namespace std; int main() { string homedir = "C:\\Users\\Tom\\Documents"; cerr << endl << "Home = " << homedir.c_str() << endl; string SrcPath = homedir + "\\Source 1"; string DestPath = homedir + "\\Dest 1\\Dest 1"; string DestPath_mkdir = "\"" + DestPath + "\""; string command = "mkdir " + DestPath_mkdir; cerr << endl << "Command = " << command.c_str() << endl << endl; system(command.c_str()); const char *arSrcPath = SrcPath.c_str(); const char *arDestPath = DestPath.c_str(); struct dirent* spnDirPtr; /* struct dirent to store all files*/ DIR* pnWriteDir = NULL; /*DIR Pointer to open Dir*/ pnWriteDir = opendir(arDestPath); if (!pnWriteDir) cerr << endl << "ERROR! Write Directory can not be open" << endl; DIR* pnReadDir = NULL; /*DIR Pointer to open Dir*/ pnReadDir = opendir(arSrcPath); if (!pnReadDir || !pnWriteDir) cerr << endl << "ERROR! Read or Write Directory can not be open" << endl << endl; else { int nErrNo = 0; while ((spnDirPtr = readdir(pnReadDir)) != NULL) { char readPath[MAX_FILE_NAME_LEN] = { 0 }; memset(readPath, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "stat" call _snprintf_s(readPath, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arSrcPath, spnDirPtr->d_name); struct stat st_buf; stat(readPath, &st_buf); if (S_ISDIR(st_buf.st_mode)) { cerr << endl << "Reading directory here..." << endl; continue; } else if (S_ISREG(st_buf.st_mode)) { if (nErrNo == 0) nErrNo = errno; cerr << endl << "Now reading and writing file " << spnDirPtr->d_name << endl; char strSrcFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strSrcFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnReadFile" _snprintf_s(strSrcFileName, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arSrcPath, spnDirPtr->d_name); FILE* pnReadFile; errno_t err_read; if ((err_read = fopen_s(&pnReadFile, strSrcFileName, "r")) == 0) { cerr << endl << "Now reading file " << strSrcFileName << endl; char strDestFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strDestFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnWriteFile" _snprintf_s(strDestFileName, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arDestPath, spnDirPtr->d_name); FILE* pnWriteFile; /*File Pointer to write in file*/ errno_t err_write; if ((err_write = fopen_s(&pnWriteFile, strDestFileName, "w")) == 0) { cerr << endl << "Now writing file " << strDestFileName << endl; char buffer[MAX] = { 0 }; /*Buffer to store files content*/ while (fgets(buffer, MAX, pnReadFile)) { fputs(buffer, pnWriteFile); } fclose(pnWriteFile); } else { cerr << endl << "Error! Unable to open file for writing " << strDestFileName << endl; } fclose(pnReadFile); } else { cerr << endl << "ERROR! File Could not be open for reading" << endl; } } } if (nErrNo != errno) cerr << endl << "ERROR Occurred!" << endl; else cerr << endl << "Process Completed" << endl << endl; } closedir(pnReadDir); closedir(pnWriteDir); return 0; } 

对于Linux Eclipse C ++:

 // CopyAll_linux.cpp : Defines the entry point for the console application. // //#include "stdafx.h" #include #include #include #include #include #include #include #include  #include  #include  #include  #define MAX 1024 #define MAX_FILE_NAME_LEN 256 using namespace std; int main() { const char *homedir; if ((homedir = getenv("HOME")) == NULL) { homedir = getpwuid(getuid())->pw_dir; } cerr << endl << "Home = " << homedir << endl; string hd(homedir); string SrcPath = hd + "/Source 1"; string DestPath = hd + "/Dest 1/Dest 1"; string DestPath_mkdir = "\"" + DestPath + "\""; string command = "mkdir -p " + DestPath_mkdir; cerr << endl << "Command = " << command.c_str() << endl << endl; system(command.c_str()); const char *arSrcPath = SrcPath.c_str(); const char *arDestPath = DestPath.c_str(); struct dirent* spnDirPtr; /* struct dirent to store all files*/ DIR* pnWriteDir = NULL; /*DIR Pointer to open Dir*/ pnWriteDir = opendir(arDestPath); if (!pnWriteDir) cerr << endl << "ERROR! Write Directory can not be open" << endl; DIR* pnReadDir = NULL; /*DIR Pointer to open Dir*/ pnReadDir = opendir(arSrcPath); if (!pnReadDir || !pnWriteDir) cerr << endl <<"ERROR! Read or Write Directory can not be open" << endl << endl; else { int nErrNo = 0; while ((spnDirPtr = readdir(pnReadDir)) != NULL) { char readPath[MAX_FILE_NAME_LEN] = { 0 }; memset(readPath, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "stat" call snprintf(readPath, MAX_FILE_NAME_LEN, "%s/%s", arSrcPath, spnDirPtr->d_name); struct stat st_buf; stat(readPath, &st_buf); if (S_ISDIR(st_buf.st_mode)) { cerr << endl << "Reading directory here..." << endl; continue; } else if (S_ISREG(st_buf.st_mode)) { if (nErrNo == 0) nErrNo = errno; cerr << endl << "Now reading and writing file "<< spnDirPtr->d_name << endl; char strSrcFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strSrcFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnReadFile" snprintf(strSrcFileName, MAX_FILE_NAME_LEN, "%s/%s", arSrcPath, spnDirPtr->d_name); FILE* pnReadFile; pnReadFile = fopen(strSrcFileName, "r"); if (pnReadFile == NULL) cerr << endl << "Null pointer on read file ..." << endl; if (pnReadFile) { cerr << endl << "Now reading file " << strSrcFileName << endl; char strDestFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strDestFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnWriteFile" snprintf(strDestFileName, MAX_FILE_NAME_LEN, "%s/%s", arDestPath, spnDirPtr->d_name); FILE* pnWriteFile = fopen(strDestFileName, "w"); /*File Pointer to write in file*/ if (pnWriteFile) { cerr << endl << "Now writing file " << strDestFileName << endl; char buffer[MAX] = { 0 }; /*Buffer to store files content*/ while (fgets(buffer, MAX, pnReadFile)) { fputs(buffer, pnWriteFile); } fclose(pnWriteFile); } else { cerr << endl << "Error! Unable to open file for writing " << strDestFileName << endl; } fclose(pnReadFile); } else { cerr << endl << "ERROR! File Could not be open for reading" << endl; } } } if (nErrNo != errno) cerr << endl << "ERROR Occurred!" << endl; else cerr << endl << "Process Completed" << endl << endl; } closedir(pnReadDir); closedir(pnWriteDir); return 0; } 

Visual Studio C ++ DLL:

  // copy_all_dll.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include #include"dirent.h" //Copy dirent.h to folder where stdafx.h is and add to project #include #include #include  #define MAX 1024 #define MAX_FILE_NAME_LEN 256 using namespace std; BOOL DirectoryExists(const char* dirName); extern "C" __declspec(dllexport) char* copy_combos_all(char *source, char *dest) { char *pnError = ""; BOOL dest_exists = DirectoryExists(dest); if (!dest_exists) { string DestPath(dest); DestPath = "\"" + DestPath + "\""; string command = "mkdir " + DestPath; system(command.c_str()); } const char *arSrcPath = source; const char *arDestPath = dest; struct dirent* spnDirPtr; /* struct dirent to store all files*/ DIR* pnWriteDir = NULL; /*DIR Pointer to open Dir*/ pnWriteDir = opendir(arDestPath); if (!pnWriteDir) { pnError = "ERROR! Write Directory can not be open"; return pnError; } DIR* pnReadDir = NULL; /*DIR Pointer to open Dir*/ pnReadDir = opendir(arSrcPath); if (!pnReadDir) { pnError = "ERROR! Read Directory can not be open"; if (pnWriteDir) { closedir(pnWriteDir); } return pnError; } else { int nErrNo = 0; while ((spnDirPtr = readdir(pnReadDir)) != NULL) { char readPath[MAX_FILE_NAME_LEN] = { 0 }; memset(readPath, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "stat" call _snprintf_s(readPath, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arSrcPath, spnDirPtr->d_name); struct stat st_buf; stat(readPath, &st_buf); if (S_ISDIR(st_buf.st_mode)) { continue; } else if (S_ISREG(st_buf.st_mode)) { if (nErrNo == 0) nErrNo = errno; char strSrcFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strSrcFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnReadFile" _snprintf_s(strSrcFileName, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arSrcPath, spnDirPtr->d_name); FILE* pnReadFile; errno_t err_read; if ((err_read = fopen_s(&pnReadFile, strSrcFileName, "r")) == 0) { char strDestFileName[MAX_FILE_NAME_LEN] = { 0 }; memset(strDestFileName, 0, MAX_FILE_NAME_LEN); // Following line needed to get real path for "pnWriteFile" _snprintf_s(strDestFileName, MAX_FILE_NAME_LEN, _TRUNCATE, "%s/%s", arDestPath, spnDirPtr->d_name); FILE* pnWriteFile; errno_t err_write; if ((err_write = fopen_s(&pnWriteFile, strDestFileName, "w")) == 0) /*File Pointer to write in file*/ { char buffer[MAX] = { 0 }; /*Buffer to store files content*/ while (fgets(buffer, MAX, pnReadFile)) { fputs(buffer, pnWriteFile); } fclose(pnWriteFile); } else { pnError = "Error! Unable to open file for writing "; return pnError; } fclose(pnReadFile); } else { pnError = "ERROR! File Could not be open for reading"; return pnError; } } } if (nErrNo != errno) { pnError = "ERROR Occurred!"; } else { pnError = "Process Completed"; } } if (pnReadDir) { closedir(pnReadDir); } if (pnWriteDir) { closedir(pnWriteDir); } return pnError; } BOOL DirectoryExists(const char* dirName) { DWORD attribs = ::GetFileAttributesA(dirName); if (attribs == INVALID_FILE_ATTRIBUTES) { return false; } return (attribs & FILE_ATTRIBUTE_DIRECTORY); } 

对于dll,您可以通过以下方式调用它:

VB.Net:

  Public Shared Function copy_all(source As String, dest As String) As StringBuilder End Function Sub copyAll() Dim source, dest, homedir As String homedir = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) source = homedir & "\Source" dest = homedir & "\Dest" If Not My.Computer.FileSystem.DirectoryExists(dest) Then My.Computer.FileSystem.CreateDirectory(dest) End If Dim errorMessage As String errorMessage = "" Dim sb As New StringBuilder() sb = copy_all(source, dest) errorMessage = sb.ToString If (errorMessage <> "") Then MessageBox.Show(errorMessage) End If End Sub 

Visual C#:

 [DllImport("copy_all.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr copy_all(string source, string dest); public void copyAll() { string homedir = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string source = homedir + "\\Source"; string dest = homedir + "\\Dest"; string error = ""; if (!Directory.Exists(dest)) Directory.CreateDirectory(dest); IntPtr ptr = copy_all(source, dest); error = Marshal.PtrToStringAnsi(ptr); if (error != "") MessageBox.Show(error); } 

@Mu Qiao提到了boost::filesystem 。 具体来说,您需要查找copy_file示例,但您也可以复制目录。

如果您对使用异步I / O感兴趣,我的印象是boost::asio有一些有趣的实现,利用平台function让您在等待磁盘时使用CPU,就像它对网络一样:

如何在C ++中执行跨平台异步文件I / O.

(注意:最近asio图书馆最近已经浮现在脑海中,但我总是要提供免责声明,我没有在项目中使用它,并且不知道它的局限性。所以请注意我的它带着一粒盐。)

还有其他跨平台库提供这种function,如果你愿意做买入,总是需要品味和需求。 我自己喜欢Qt有很多原因,它确实提供了一个QFile::copy方法:

http://doc.qt.nokia.com/latest/qfile.html#copy

 /* * * Module : Copy Multiple from Src dir to Dest dir * Author : Mohd Asif * Date : 12-March-2013 * Description : This code will copy all the files from Src dir to Dest Dir * instead of onother directory inside src dir * */ #include #include #include #include #include #include #define MAX 1024 int main() { char arSrcPath[] = "/home/mpe4/Src"; /*Source directory path*/ char arDestPath[] = "/home/mpe4/Dest"; /*dest directory path*/ struct dirent* spnDirPtr; /* struct dirent to store all files*/ DIR* pnOpenDir = NULL; /*DIR Pointer to open Dir*/ DIR* pnReadDir = NULL; /*DIR POinter to read directory*/ pnOpenDir = opendir(arSrcPath); if(!pnOpenDir) printf("\n ERROR! Directory can not be open"); else { int nErrNo = 0; while(spnDirPtr = readdir(pnOpenDir)) { if(nErrNo == 0) nErrNo = errno; printf("\n Now writing %s file...",spnDirPtr->d_name); printf("\n dest file name = %s/%s\n", arDestPath, spnDirPtr->d_name); struct stat st_buf; stat(spnDirPtr->d_name, &st_buf); if (S_ISDIR (st_buf.st_mode)) { continue; } else if (S_ISREG (st_buf.st_mode)) { FILE* pnReadFile = fopen(spnDirPtr->d_name,"r"); if(pnReadFile) { printf("\n Now reading %s file...",spnDirPtr->d_name); char strDestFileName[MAX] = {0}; sprintf(strDestFileName, "%s/%s", arDestPath, spnDirPtr->d_name); printf("\n dest file name = %s\n", strDestFileName); FILE* pnWriteFile = fopen(strDestFileName, "w"); /*File Pointer to write in file*/ if(pnWriteFile) { char buffer[MAX] = {0}; /*Buffer to store files content*/ while(fgets(buffer, MAX, pnReadFile)) { fputs(buffer, pnWriteFile); } fclose(pnWriteFile); } else { printf("\n Unable to open file %s", strDestFileName); } fclose(pnReadFile); } else { printf ("\nERROR! File Could not be open for reading"); } } } if(nErrNo != errno) printf ("\nERROR Occurred!\n"); else printf ("\nProcess Completed\n"); } closedir(pnOpenDir); return 0; } 

另一种选择是这样的:

 #ifdef SOME_OS #define COPY_STR "copy %s %s" // some sort of OS-specific syntax #elif defined SOME_OTHER_OS #define COPY_STR "%s cpy %s" // some sort of OS-specific syntax #else #error "error text" #endif 

 #include  //sprintf() #include  //system() char copy_str[LARGE_ENOUGH]; char* source; char* dest; ... sprintf (copy_str, COPY_STR, source, dest); system (copy_str); 

我对@ te7的答案做了一些修改,只在MAC上将一个文件从一个文件夹复制到另一个文件夹。 我试图修改他的代码只是复制一个文件,但它部分写入文件到目的地。 所以我使用不同的代码进行文件读/写

 void copyFile(string srcDirPath, string destDirPath, string fileName) { string command = "mkdir -p " + destDirPath; cerr << endl << "Command = " << command.c_str() << endl << endl; system(command.c_str()); DIR* pnWriteDir = NULL; /*DIR Pointer to open Dir*/ pnWriteDir = opendir(destDirPath.c_str()); if (!pnWriteDir) cerr << endl << "ERROR! Write Directory can not be open" << endl; DIR* pnReadDir = NULL; /*DIR Pointer to open Dir*/ pnReadDir = opendir(srcDirPath.c_str()); if (!pnReadDir || !pnWriteDir) cerr << endl <<"ERROR! Read or Write Directory can not be open" << endl << endl; else { string srcFilePath = srcDirPath + fileName; const char * strSrcFileName = srcFilePath.c_str(); fstream in, out; in.open(strSrcFileName, fstream::in|fstream::binary); if (in.is_open()) { cerr << endl << "Now reading file " << strSrcFileName << endl; string destFilePath = destDirPath + fileName; const char * strDestFileName = destFilePath.c_str(); out.open(strDestFileName, fstream::out); char tmp; while(in.read(&tmp, 1)) { out.write(&tmp, 1); } out.close(); in.close(); } else cerr << endl << "ERROR! File Could not be open for reading" << endl; } closedir(pnReadDir); closedir(pnWriteDir); }