最近整理了一下使用C++语言实现文件读写,比较简单,直接贴上代码:
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>
#define SERIAL_NO_LEN 32
#define NAME_LEN 32
#define GENDER_LEN 8
#define PHONE_LEN 16
#define AGE_LEN 16
#define SALARY_LEN 16
#define STAFF_SIZE 3
#define STAFF_FILE_NAME "staff_info.txt"
struct Staff
{
char szSerialNo[SERIAL_NO_LEN];
char szName[NAME_LEN];
char szGender[GENDER_LEN];
char szPhone[PHONE_LEN];
int iAge;
double dSalary;
void show()
{
std::cout << szSerialNo << '\t' << szName << '\t' << szGender << '\t'
<< szPhone << '\t' << iAge << '\t' << dSalary << std::endl;
}
};
void fileReadTest()
{
std::ifstream fin(STAFF_FILE_NAME);
if (!(fin.is_open()))
{
std::cout << "打开文件错误!" << std::endl;
return;
}
// 方式一:按行读取
/*char szInfo[256] = { 0 };
while (!(fin.eof()))
{
fin.getline(szInfo, 255);
std::cout << szInfo << std::endl;
}*/
// 方式二:string按行读
/*std::string strInfo = "";
getline(fin, strInfo);
std::cout << "Tag: "<< strInfo.c_str() << std::endl;
getline(fin, strInfo);
std::cout << "Count: "<< strInfo.c_str() << std::endl;
getline(fin, strInfo);
std::cout << strInfo.c_str() << std::endl;*/
// 注意:各种方式不能混合使用,混合使用出现读取错乱
// 方式三:根据数据类型读取
int iTag = 0, iCount = 0;
fin >> iTag >> iCount;
//fin >> iCount;
std::cout << "Tag: " << iTag << ", count: " << iCount << std::endl;
char szSerialNo[SERIAL_NO_LEN] = { 0 };
char szName[NAME_LEN] = { 0 };
char szGender[GENDER_LEN] = { 0 };
char szPhone[PHONE_LEN] = { 0 };
char szAge[AGE_LEN] = { 0 };
char szSalary[SALARY_LEN] = { 0 };
fin >> szSerialNo >> szName >> szGender >> szPhone >> szAge >> szSalary;
std::cout << szSerialNo << '\t' << szName << '\t' << szGender << '\t'
<< szPhone << '\t' << szAge << '\t' << szSalary << std::endl;
Staff staff;
for (int i = 0; i < iCount; ++i)
{
memset(&staff, 0, sizeof (staff));
fin >> staff.szSerialNo >> staff.szName >> staff.szGender >> staff.szPhone >> staff.iAge >> staff.dSalary;
staff.show();
}
fin.close();
return;
}
void fileWriteTest()
{
int iTag = 2;
Staff szStaffs[STAFF_SIZE] = { 0 };
strcpy(szStaffs[0].szSerialNo, "ST000001");
strcpy(szStaffs[0].szName, "张三");
strcpy(szStaffs[0].szGender, "男");
strcpy(szStaffs[0].szPhone, "15656697812");
szStaffs[0].iAge = 25;
szStaffs[0].dSalary = 4568.23;
strcpy(szStaffs[1].szSerialNo, "ST000002");
strcpy(szStaffs[1].szName, "蔡明花");
strcpy(szStaffs[1].szGender, "女");
strcpy(szStaffs[1].szPhone, "15156647862");
szStaffs[1].iAge = 23;
szStaffs[1].dSalary = 3569.04;
strcpy(szStaffs[2].szSerialNo, "ST000003");
strcpy(szStaffs[2].szName, "李四");
strcpy(szStaffs[2].szGender, "男");
strcpy(szStaffs[2].szPhone, "13856748869");
szStaffs[2].iAge = 56;
szStaffs[2].dSalary = 9549.57;
std::ofstream fout(STAFF_FILE_NAME); // std::ofstream fout(STAFF_FILE_NAME, ios::app);
if (!(fout.is_open()))
{
std::cout << "打开文件错误!" << std::endl;
return;
}
fout << iTag << std::endl;
fout << STAFF_SIZE << std::endl;
fout << "编号" << '\t' << "姓名" << '\t' << "性别" << '\t'
<< "电话" << '\t' << "年龄" << '\t' << "工资" << std::endl;
for (int i = 0; i < STAFF_SIZE; ++i)
{
szStaffs[i].show();
fout << szStaffs[i].szSerialNo << '\t' << szStaffs[i].szName << '\t' << szStaffs[i].szGender << '\t'
<< szStaffs[i].szPhone << '\t' << szStaffs[i].iAge << '\t' << szStaffs[i].dSalary << std::endl;
}
fout.close();
return;
}
int main(int argc, char** argv)
{
fileWriteTest();
fileReadTest();
getchar();
return 0;
}
再补充直接读写std::string中的接口和测试接口
#include <sstream>
#include <fstream>
#include <algorithm>
#include <string>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
// 内容追加入文件
void appendFile(const std::string& strFilePath, const std::string& strContent)
{
std::ofstream fout;
fout.open(strFilePath, std::ios::app | std::ios::binary | std::ios::out);
if (!(fout.is_open()))
{
LOG_ERROR("open file (%s) failed.", strFilePath.data());
return;
}
fout << strContent;
fout.flush();
fout.close();
return;
}
// 写入文件
void writeFile(const std::string& strFilePath, const std::string& strContent)
{
#if 1
// 效率ok
int fd = open(strFilePath.data(), O_RDWR | O_CREAT | O_TRUNC, 0777);
if (0 <= fd)
{
size_t len = strContent.length();
truncate(strFilePath.data(), len);
void *mp = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
if (mp)
{
memcpy(mp, strContent.data(), len);
munmap(mp, len);
}
close(fd);
}
#elif 0
// 效率差不多
std::ofstream fout(strFilePath, std::ios::binary | std::ios::out); // 需要指定模式,否则存在数据丢失问题
if (!(fout.is_open()))
{
LOG_ERROR("open file (%s) failed.", strFilePath.data());
return;
}
fout << strContent;
fout.flush();
fout.close();
#else
// 效率差不多
FILE *fp = fopen(strFilePath.data(), "wb+"); // 注意只用w或者wb时,存在数据丢失问题,建议用wb+
if (fp)
{
// fputs(strContent.data(), fp);
fwrite(strContent.data(), strContent.size(), 1, fp);
fflush(fp);
fclose(fp);
}
#endif
return;
}
// 读出文件
void readFile(const std::string& strFilePath, std::string& strContent)
{
std::ifstream fin(strFilePath);
if (!(fin.is_open()))
{
printf("open file (%s) failed.\r\n", strFilePath.data());
return;
}
#if 0
// 方法1:ok
std::istreambuf_iterator<char> iterBeg(fin), iterEnd;
strContent = std::string(iterBeg, iterEnd);
//fin >> strContent;
#elif 0
// 方法2:ok
fin.seekg(0, std::ios::end); // 跳到文件尾
size_t iFileSize = fin.tellg(); // 获取字节长度
fin.seekg(0, std::ios::beg); // 跳到文件开头
char* pBuffer = new (std::nothrow) char[iFileSize];
if (pBuffer)
{
memset(pBuffer, 0, iFileSize * sizeof(char));
fin.read(pBuffer, iFileSize); // 读取文件
strContent = std::string(pBuffer, iFileSize);
delete[] pBuffer;
pBuffer = nullptr;
}
#else
// 方法3(推荐):ok,该方法效率较一般读取方法快20倍
std::vector<char> buffer;
buffer.clear();
buffer.resize(fin.seekg(0, std::ios::end).tellg());
fin.seekg(0, std::ios::beg).read(&buffer[0], static_cast<std::streamsize>(buffer.size()));
strContent = std::string(buffer.data(), buffer.size());
#endif // 0
fin.close();
return;
}
void fileTest()
{
std::string strFilePath = "abc123.txt";
std::string strContent = "abc123456789 0000 \r\n7891212abcdfghijklmn.";
std::string strContentTemp = "";
writeFile(strFilePath, strContent);
readFile(strFilePath, strContentTemp);
printf("read: %s\r\n", strContentTemp.data());
return;
}