Last active
January 10, 2022 09:59
-
-
Save pk13610/234430b96c0f38ef94e55fafab590257 to your computer and use it in GitHub Desktop.
create files on windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <chrono> | |
#include <string> | |
#include <string.h> | |
#include <iostream> | |
#include <fstream> | |
#include <sys/stat.h> // stat | |
#include <errno.h> // errno, ENOENT, EEXIST | |
#if defined(_WIN32) | |
# include <direct.h> // _mkdir | |
# if defined(_MSC_VER) && _MSC_VER < 1900 | |
# ifndef snprintf | |
# define snprintf _snprintf | |
# endif | |
# endif | |
#endif | |
namespace utils { | |
; | |
bool isDirExist(const std::string& path) | |
{ | |
#if defined(_WIN32) | |
struct _stat info; | |
if (_stat(path.c_str(), &info) != 0) | |
{ | |
return false; | |
} | |
return (info.st_mode & _S_IFDIR) != 0; | |
#else | |
struct stat info; | |
if (stat(path.c_str(), &info) != 0) | |
{ | |
return false; | |
} | |
return (info.st_mode & S_IFDIR) != 0; | |
#endif | |
} | |
bool makePath(const std::string& path) | |
{ | |
#if defined(_WIN32) | |
int ret = _mkdir(path.c_str()); | |
#else | |
mode_t mode = 0755; | |
int ret = mkdir(path.c_str(), mode); | |
#endif | |
if (ret == 0) | |
return true; | |
switch (errno) | |
{ | |
case ENOENT: | |
// parent didn't exist, try to create it | |
{ | |
auto pos = path.find_last_of('/'); | |
if (pos == std::string::npos) | |
#if defined(_WIN32) | |
pos = path.find_last_of('\\'); | |
if (pos == std::string::npos) | |
#endif | |
return false; | |
if (!makePath(path.substr(0, pos))) | |
return false; | |
} | |
// now, try to create again | |
#if defined(_WIN32) | |
return 0 == _mkdir(path.c_str()); | |
#else | |
return 0 == mkdir(path.c_str(), mode); | |
#endif | |
case EEXIST: | |
// done! | |
return isDirExist(path); | |
default: | |
return false; | |
} | |
} | |
class TimeInterval | |
{ | |
// use steady_clock only | |
// ref: https://stackoverflow.com/questions/38252022/does-standard-c11-guarantee-that-high-resolution-clock-measure-real-time-non | |
static_assert( | |
std::is_same<std::chrono::high_resolution_clock, std::chrono::steady_clock>::value | |
|| std::is_same<std::chrono::high_resolution_clock, std::chrono::system_clock>::value, | |
"high_resolution_clock IS NOT aliased to one of the other standard clocks!"); | |
typedef | |
std::conditional< | |
std::chrono::system_clock::period::den <= std::chrono::steady_clock::period::den, | |
std::chrono::system_clock, std::chrono::steady_clock | |
>::type maxres_sys_or_steady; | |
typedef | |
std::conditional< | |
std::chrono::high_resolution_clock::is_steady, | |
std::chrono::high_resolution_clock, maxres_sys_or_steady | |
>::type maxres_nonsleeping_clock; | |
//typedef std::chrono::high_resolution_clock maxres_nonsleeping_clock; | |
typedef std::chrono::time_point<maxres_nonsleeping_clock> time_point_t; | |
public: | |
TimeInterval() | |
{ | |
reset(); | |
} | |
void reset() | |
{ | |
first_ = maxres_nonsleeping_clock::now(); | |
} | |
void tick() | |
{ | |
interval_ = get_interval_nano_(); | |
} | |
long long ns() const | |
{ | |
return interval_; | |
} | |
long long ms() const | |
{ | |
return ns() / 1000000; | |
} | |
long long sec() const | |
{ | |
return ms() / 1000000; | |
} | |
long long ns_total() const | |
{ | |
const auto now = maxres_nonsleeping_clock::now(); | |
const auto delta = now - first_; | |
return std::chrono::duration_cast<std::chrono::nanoseconds>(delta).count(); | |
} | |
long long ms_total() const | |
{ | |
return ns_total() / 1000000; | |
} | |
long long sec_total() const | |
{ | |
return ms_total() / 1000000; | |
} | |
protected: | |
long long get_interval_nano_() | |
{ | |
const auto now = maxres_nonsleeping_clock::now(); | |
const auto delta = now - last_; | |
last_ = now; | |
return std::chrono::duration_cast<std::chrono::nanoseconds>(delta).count(); | |
} | |
protected: | |
time_point_t last_; | |
time_point_t first_; | |
long long interval_; | |
}; | |
} // namespace utils | |
int generate_files(int argc, char* argv[]) | |
{ | |
if (argc <= 1) | |
{ | |
std::cout << "useage: ./cfiles <path <count <prefix>>>" << std::endl; | |
return -1; | |
} | |
std::string path = "./111/"; | |
int count = 10000; | |
std::string prefix = "a"; | |
if (argc > 1) path = argv[1]; | |
if (argc > 2) count = atoi(argv[2]); | |
if (argc > 3) prefix = argv[3]; | |
int ccount = 0; | |
char buff[500] = { 0 }; | |
snprintf(buff, sizeof(buff), "%s/%s_", path.c_str(), prefix.c_str()); | |
char* ptr = buff + strlen(buff); | |
const auto buff1_size = sizeof(buff) - strlen(buff); | |
utils::makePath(path); | |
utils::TimeInterval t; | |
t.tick(); | |
for (ccount=0; ccount < count; ++ccount) | |
{ | |
snprintf(ptr, buff1_size, "%d", ccount+1); | |
std::fstream fs; | |
fs.open(buff, std::fstream::out); | |
if (fs.is_open()) | |
{ | |
fs.close(); | |
if (ccount > 0 && ccount % 10000 == 0) | |
{ | |
std::cout << ccount << " [" << t.ms_total() << "ms]" << std::endl; | |
} | |
} | |
else | |
{ | |
std::cout << "errno: " << strerror(errno) << ", " << buff << std::endl; | |
} | |
} | |
t.tick(); | |
std::cout << ccount << " [" << t.ms_total() << "ms]" << std::endl; | |
return ccount; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
generate_files(argc, argv); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment