Convert from CSV file to “JSON file” of “TFDMemTable format”.
This program uses C++Builder 10.2 Tokyo Release 1.
include
#include <iostream> #include <fstream> #include <string> #include <codecvt> #include <FireDAC.Comp.Client.hpp> #include <FireDAC.Stan.StorageJSON.hpp> #include <FireDAC.Stan.Intf.hpp> #include <memory> #include <vector> #include <sstream> #include <mutex> #include <thread> #include <chrono>
code
struct _Tcsv_to_memtable { std::mutex mx_; std::vector<std::thread> vth_; std::unique_ptr<TFDMemTable> mem_table_{std::make_unique<TFDMemTable>(nullptr</span>)}; std::unique_ptr<TFDStanStorageJSONLink> jl_{std::make_unique<TFDStanStorageJSONLink>(nullptr</span>)}; void create_column(std::vector<String>& v) { //Field creation of "TFDMemTable" //The field name is the first line of CSV File for (auto s: v) { auto fld = mem_table_->FieldDefs->AddFieldDef(); //Discard the "BOM (Byte Order Mark)" if present. fld->Name = StringReplace(s, L'\x0feff', "", TReplaceFlags()); fld->DataType = TFieldType::ftWideString; } mem_table_->Active = true</span>; } void create_line(std::vector<String>& v) { //Add 1 line of "CSV File" to "TFDMemTable" int i{0</span>}; mem_table_->Append(); for (auto s: v) { //One item for one field. mem_table_->Fields->operator[](i)->AsWideString = s; ++i; } mem_table_->Post(); } void create_line(std::wstring ws, int line_num) { std::lock_guard<std::mutex> lk(mx_); if (ws.length() > 0) { //Inserted by dividing one line of CSV File to vector<String>. std::vector<String> v1; std::wstring column_data; std::wistringstream line_data(ws); while (std::getline(line_data, column_data, L',')) { v1.push_back(column_data.c_str()); } switch (line_num) { case 0: create_column(v1); break</span>; default: create_line(v1); } } } void threads_join() { //Wait for the termination of all threads. for (auto& th: vth_) { th.join(); } } }; int _tmain(int argc, _TCHAR* argv[]) { std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); _Tcsv_to_memtable memtable_; UnicodeString argv_ = argv[1</span>]; //Specify CSV Fire for input. UnicodeString arg_o_ = argv[2</span>]; //JSON output destination specification made with "TFDMemTable". if (FileExists(argv_)) { std::wfstream file_; file_.open(argv_.w_str(), std::ios::in); //The CSV file is utf8 format. file_.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>)); std::wstring buff; int line_num_{0</span>}; while (std::getline(file_, buff)) { //The append processing to "TFDMemTable" threads line by line. memtable_.vth_.push_back(std::thread([&memtable_, &buff, line_num_](){ memtable_.create_line(buff, line_num_); })); //Since the command line is multibyte, AnsiString conversion is done. AnsiString as_ = buff.c_str(); std::cout << as_ << std::endl; ++line_num_; } memtable_.threads_join(); //Finally, save the TFDMemTable contents as a JSON file. memtable_.mem_table_->SaveToFile(arg_o_, TFDStorageFormat::sfJSON); } auto keika = std::chrono::system_clock::now() - now; std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(keika).count(); std::cout << " millisecond." << std::endl ; return 0</span>; }
There is a project file in github, you can try it right away.
GitHub – mojeld/csvfstream_to_TFDMemTable: Create json file of TFDMemTable format from CSV file.