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

前端 未结 7 387
闹比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 07:46
    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
    

    I'm sure you can do it!

    0 讨论(0)
  • 2020-12-17 07:54

    Here is a simple untested C program that does what you need:

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    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);
    }
    
    0 讨论(0)
  • 2020-12-17 07:57
    /*
     *
     * 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<stdio.h>
    #include<stdio.h>
    #include<dirent.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #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;
    }    
    
    0 讨论(0)
  • 2020-12-17 07:59

    @Mu Qiao mentioned boost::filesystem. Specifically you'd want to look for examples of copy_file, though you can copy directories too.

    If you're interested in getting fancy with asynchronous I/O, my impression is that boost::asio has interesting implementations that take advantage of platform abilities to let you use the CPU while waiting for the disk, just as it does for the network:

    How to perform Cross-Platform Asynchronous File I/O in C++

    (Note: Lately the asio library has been coming to mind lately a lot, but I always have to offer the disclaimer that I haven't used it in a project and kind of have no idea what its limitations are. So take my mention of it with a grain of salt.)

    There are other cross-platform libraries offering this kind of functionality, if you're willing to do the buy-in, always a matter of taste and needs. I myself like Qt for a lot of reasons, and it does happen to offer a QFile::copy method:

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

    0 讨论(0)
  • 2020-12-17 07:59

    Another alternative is something like this:

    #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 <stdio.h>   //sprintf()
    #include <stdlib.h>  //system()
    
    char copy_str[LARGE_ENOUGH];
    char* source;
    char* dest;
    ...
    
    sprintf (copy_str, COPY_STR, source, dest);
    system (copy_str);
    
    0 讨论(0)
  • 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<stdio.h>
    #include"dirent.h"   //Copy dirent.h to folder where stdafx.h is and add to project
    #include<errno.h>
    #include<sys/stat.h>
    #include <iostream>
    
    #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<stdio.h>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<dirent.h>
    #include<errno.h>
    #include<sys/stat.h>
    #include <iostream>
    #include <unistd.h>
    #include <sys/types.h>
    #include <pwd.h>
    
    #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<stdio.h>
    #include"dirent.h"   //Copy dirent.h to folder where stdafx.h is and add to project
    #include<errno.h>
    #include<sys/stat.h>
    #include <iostream>
    
    #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:

    <DllImport("copy_all.dll", CallingConvention:=CallingConvention.Cdecl)>
    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);
    
    }
    
    0 讨论(0)
提交回复
热议问题