我正在寻找一个关于如何在C中将文件从一个目录复制到另一个目录的简单示例。该程序应该只使用C本机的跨平台函数。
答案 0 :(得分:6)
这是一个简单的未经测试的C程序,可以满足您的需求:
#include <stdio.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);
}
答案 1 :(得分:4)
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
我相信你能做到!
答案 2 :(得分:2)
下面是使用dirent.h在C ++中复制文件的正确方法。请注意,dirent.h是Linux的一部分,但不包含在Windows中。对于Windows,请查看here。
对于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:
<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);
}
答案 3 :(得分:1)
@Mu Qiao提到boost::filesystem
。具体来说,您需要查找copy_file
的示例,但您也可以复制目录。
如果您对使用异步I / O感兴趣,我的印象是boost::asio
有一些有趣的实现,利用平台功能让您在等待磁盘时使用CPU,就像它一样为网络做的:
How to perform Cross-Platform Asynchronous File I/O in C++
(注意:最近asio库已经开始考虑了很多,但我总是要提供免责声明,我没有在项目中使用它,并且不知道它的局限性是什么所以我带着一点点盐就提到了它。)
还有其他跨平台的库提供这种功能,如果你愿意做买入,总是需要品味和需求。我自己喜欢Qt有很多原因,它确实提供了QFile::copy
方法:
答案 4 :(得分:1)
/*
*
* 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;
}
答案 5 :(得分: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 <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);
答案 6 :(得分:0)
我对@ 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);
}