fork(1) download
  1. #include <windows.h>
  2. #include <iostream>
  3. #include <stack>
  4.  
  5. int const BuffSize = 65536;
  6. bool MyCopyFile(std::string src, std::string dest) {
  7. static char Buff[BuffSize];
  8. DWORD ActualReadBytes, ActualWriteBytes;
  9. HANDLE hFileSrc, hFileDest;
  10.  
  11. hFileSrc = ::CreateFile(src.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  12. if (hFileSrc == INVALID_HANDLE_VALUE) {
  13. std::cerr << "Cannot open(read) :" << src << std::endl;
  14. return false;
  15. }
  16.  
  17. hFileDest = ::CreateFile(dest.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  18. if (hFileSrc == INVALID_HANDLE_VALUE) {
  19. std::cerr << "Cannot open(write) :" << dest << std::endl;
  20. ::CloseHandle(hFileSrc);
  21. return false;
  22. }
  23.  
  24. int nReadTotalBytes = 0;
  25. int nWriteTotalBytes = 0;
  26.  
  27. for (;;) {
  28. if (!::ReadFile(hFileSrc, Buff, BuffSize, &ActualReadBytes, 0)) {
  29. std::cerr << "Opend but cannot read: " << src << " : " << nReadTotalBytes << "/" << nWriteTotalBytes << std::endl;
  30. ::CloseHandle(hFileSrc);
  31. ::CloseHandle(hFileDest);
  32. return false;
  33. }
  34. nReadTotalBytes += ActualReadBytes;
  35.  
  36. /* out of loop */
  37. if (ActualReadBytes == 0)
  38. break;
  39.  
  40. if(!::WriteFile(hFileDest, Buff, ActualReadBytes, &ActualWriteBytes, 0)) {
  41. std::cerr << "Opend and read but cannot write: " << dest << " : " << nReadTotalBytes << "/" << nWriteTotalBytes << std::endl;
  42. break; /* out of for (;;) */
  43. }
  44. nWriteTotalBytes += ActualWriteBytes;
  45. }
  46. std::cout << nReadTotalBytes << "/" << nWriteTotalBytes << " ";
  47. ::CloseHandle(hFileSrc);
  48. ::CloseHandle(hFileDest);
  49. return true;
  50. }
  51.  
  52. struct PathPair {
  53. std::string src;
  54. std::string dest;
  55. PathPair(std::string src, std::string dest) : src(src), dest(dest) { }
  56. };
  57.  
  58. std::stack<PathPair> path_stack;
  59.  
  60. void copy_body(std::string original_dest) {
  61. while (!path_stack.empty()) {
  62. PathPair path_pair = path_stack.top(); path_stack.pop();
  63. std::string now_path = path_pair.src;
  64. std::string now_dest_path = path_pair.dest;
  65.  
  66. if (now_path.find_last_of(std::string("/")) != now_path.length() - 1) now_path += "/"; /* '/' で終わらない場合に '/' を追加 */
  67. if (now_dest_path.find_last_of(std::string("/")) != now_dest_path.length() - 1) now_dest_path += "/"; /* '/' で終わらない場合に '/' を追加 */
  68. std::string now_path_findfirst = now_path + "*.*";
  69.  
  70. WIN32_FIND_DATA FindFileData;
  71.  
  72. HANDLE hFindFirstNext = ::FindFirstFile(now_path_findfirst.c_str(), &FindFileData);
  73. bool bInLoop = (hFindFirstNext != INVALID_HANDLE_VALUE);
  74.  
  75. while (bInLoop) {
  76. std::string now_path_filename;
  77. std::string now_dest_path_filename;
  78. std::string filename = std::string(FindFileData.cFileName);
  79.  
  80. if (filename == "." || filename == "..") goto FINDNEXTFILE;
  81.  
  82. now_path_filename = now_path + filename;
  83. now_dest_path_filename = now_dest_path + filename;
  84.  
  85. /* prevent recursively-endless-loop */
  86. if (now_path_filename == original_dest)
  87. goto FINDNEXTFILE;
  88.  
  89. if (::GetFileAttributes(now_path_filename.c_str()) & FILE_ATTRIBUTE_DIRECTORY) { /* when now_path_filename is a directory */
  90. if ((signed int)::GetFileAttributes(now_dest_path_filename.c_str()) == -1) {
  91. if(::CreateDirectory(now_dest_path_filename.c_str(), 0)) {
  92. std::cout << "Create directory: " << now_dest_path_filename << std::endl;
  93. } else {
  94. std::cerr << "Failure to create directory: " << now_dest_path_filename << std::endl;
  95. break;
  96. }
  97. }
  98. path_stack.push(PathPair(now_path_filename, now_dest_path_filename));
  99.  
  100. } else { /* when now_path_filename is a file */
  101. std::cout << now_path_filename << " -> " << now_dest_path_filename << " ";
  102. if (MyCopyFile(now_path_filename, now_dest_path_filename)) {
  103. std::cout << " : OK" << std::endl;
  104. }
  105. }
  106. FINDNEXTFILE:
  107. bInLoop = ::FindNextFile(hFindFirstNext, &FindFileData);
  108. } /* while(bInLoop) */
  109. if (hFindFirstNext != INVALID_HANDLE_VALUE)
  110. ::FindClose(hFindFirstNext);
  111. } /* while(!path_stack.empty()) */
  112. }
  113.  
  114. int main(int argc, char *argv[]) {
  115.  
  116. if (argc != 3) {
  117. std::cerr << argv[0] << " : copy files and directory recursively." << std::endl;
  118. std::cerr << "usage: " << argv[0] << " src-path dest-path " << std::endl;
  119. return 0;
  120. }
  121.  
  122. std::string src = std::string(argv[1]);
  123. std::string dest= std::string(argv[2]);
  124.  
  125. if (src.find(std::string("./")) != 0)
  126. src = std::string("./") + src;
  127. if (dest.find(std::string("./")) != 0)
  128. dest = std::string("./") + dest;
  129.  
  130. int attributes = ::GetFileAttributes(dest.c_str());
  131. if (attributes == -1) {
  132. std::cerr << "Directory: " << dest << " is not exists, aborted." << std::endl;
  133. return 0;
  134. }
  135.  
  136. path_stack.push(PathPair(src, dest));
  137. copy_body(dest);
  138.  
  139. return 0;
  140. }
  141. /* end */
  142.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:21: fatal error: windows.h: No such file or directory
 #include <windows.h>
                     ^
compilation terminated.
stdout
Standard output is empty