How can I copy a file from one directory to another in c/c++

前端 未结 7 418
闹比i
闹比i 2020-12-17 07:18

I am looking for a simple example on how to copy a file from one directory to another in C. The program should only use cross platform functions that are native to C.

7条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-17 08:02

    The correct way to copy files in C++ using dirent.h is below. Note that dirent.h is part of Linux but not included in Windows. For Windows look here.

    For 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;
    }
    

    For 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);
    }
    

    For the dll, you call call it as following:

    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);
    
    }
    

提交回复
热议问题