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

发布于 2024-12-02 19:24:40 字数 65 浏览 7 评论 0原文

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

旧城空念 2024-12-09 19:24:40

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

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

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);
}
忆梦 2024-12-09 19:24:40
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

我相信你能做到!

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!

等往事风中吹 2024-12-09 19:24:40

使用 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<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;
}

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

对于 dll,您可以按如下方式调用它:

VB.Net:Visual

<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

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

}

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

}
肥爪爪 2024-12-09 19:24:40

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

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

如何执行交叉-平台异步文件C++ 中的 I/O

(注意:最近我经常想到 asio 库,但我总是必须提供免责声明,即我没有在项目中使用过它,并且有点不知道它的局限性是什么。所以请对我提到的持保留态度。)

还有其他跨平台库提供这种功能,如果您愿意购买的话,总是可以的。品味和需求的问题。我自己喜欢 Qt 有很多原因,而且它确实提供了 QFile::copy 方法:

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

@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

陌伤浅笑 2024-12-09 19:24:40

另一种选择是这样的:

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

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);
罪#恶を代价 2024-12-09 19:24:40
/*
 *
 * 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;
}    
/*
 *
 * 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;
}    
我的鱼塘能养鲲 2024-12-09 19:24:40

我对 @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);
}

I made some changes to @te7 answer to copy just one file from one folder to another on MAC. I tried to modify his code to just copy one file but it was partially writing file to destination. So I use different code for file read/write

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文