最近在看Linux,受到“Linux一切皆文件”所启发,就想用上会的编程语言来整理读写文件的实现方法。
以下的实现是基于Windows,不知道在Linux中个别的是否还适用,等Linux学习到一定道道之后再回来更新。
1、C/C++的读写文件
1.1 Read
以下以读取ini文件为例
[sectrion]
key=value
//(int)为初始化文件中指定的条目获取它的整数值;
//返回值,即为找到的;若没找到,则返回默认值;若找到的不是合法整数,则返回合法的部分。
WINBASEAPI UINT WINAPI GetPrivateProfileInt(
_In_ LPCSTR lpAppName, //section 名称
_In_ LPCSTR lpKeyName, //key 名称
_In_ INT nDefault, //如果没找到则返回默认值
_In_opt_ LPCSTR lpFileName // 文件路径
);
//(string)为初始化文件中指定的条目取得字符串
WINBASEAPI DWORD WINAPI GetPrivateProfileString(
_In_opt_ LPCSTR lpAppName, //section 名称
_In_opt_ LPCSTR lpKeyName, //key 名称
_In_opt_ LPCSTR lpDefault, //如果没找到则返回默认值
_Out_writes_to_opt_(nSize, return + 1) LPSTR lpReturnedString, //指定存储字符串的缓冲区,长度至少为nSize
_In_ DWORD nSize, //指定装载到lpReturnedString缓冲区的最大字符数量
_In_opt_ LPCSTR lpFileName // 文件路径
);
1.2 Write
int log_write(char* msg)
{
char m_buf[1024] = { 0 };
//时间
char time_buf[64] = { 0 }; //时间戳信息
time_t _timet = time(0);
tm *t = localtime(&_timet);
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", t);
sprintf(m_buf, "%s %s", time_buf, msg);
//写
out << m_buf << endl;
return 0;
}
ofstream out;
const char* logpath = "C:\\ProgramData\\testlog.ini";
out.open(testlogpath, ios::out);
log_write("hello world");
out.close();
2、C#的读写文件
2.1 Read
1)一般性文件的读取
引入直接将字符和字符串读取文件的 StreamReader 类
StreamReader sReader = new StreamReader(filePath);
string sLineR = "";
int lineIndx = 1, i = 0;
while (!sReader.EndOfStream)
{
sLineR += sReader.ReadLine();
}
sReader.Close();
2)ini文件的读取
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string iniPath);
/// <summary>
/// 读取section下的key对应的value并返回;若找不到则返回def中的字符串。
/// </summary>
/// <param name="iniPath">ini文件的绝对路径</param>
/// <param name="section">section名</param>
/// <param name="key">key名</param>
/// <param name="def">默认value字符串</param>
/// <returns>key对应的value</returns>
public static string iniReadValue(string iniPath, string section, string key, string def = "")
{
try
{
int size = 255;
StringBuilder retVal = new StringBuilder(size);
GetPrivateProfileString(section, key, def, retVal, size, iniPath);
return retVal.ToString().Trim();
}
catch
{
return def;
}
}
2.2 Write
1)一般性文件的写入
引入直接将字符和字符串写入文件的 StreamWriter 类(一般不针对二进制数据)。
最直接简单字符串写入:
string path="C:\\ProgramData\\Test.csv";
StreamWriter sw = new StreamWriter(path, false); //往文件写入流,path是文件路径名,false表示覆盖文件内容/true表示追加数据到文件中
sw.WriteLine("a,b,c,d"); //写入的数据
sw.Close(); //关闭对象和流
带有一定格式的:
//获取新建的StreamWriter 对象
private static StreamWriter GetStreamWriter(string path, bool append)
{
FileInfo fi = new FileInfo(path);
DirectoryInfo di = fi.Directory;
if (!di.Exists) di.Create();
return new StreamWriter(path, append);
}
//写入文件
public static void WriteMsg2File(string msg)
{
//以带日期时间为文件名,格式是.log
using (StreamWriter sWriter = GetStreamWriter(parentPath + @"\Log" + date + ".log", true))
{
sWriter .WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]" + msg);
sWriter .Flush();
sWriter .Close();
}
}
2)ini文件的写入(特殊格式文件)
一般性的配置文件以ini文件保存,格式上为section和key来存储。如:
//section为Test,Key为Name
[Test]
Name=Jone
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string iniPath);
/// <summary>
/// 为iniPath的ini文件添加相应的section、key和value,或者覆盖原有段、键对应的键值。
/// </summary>
/// <param name="iniPath">ini文件的绝对路径</param>
/// <param name="section">段名</param>
/// <param name="key">键名</param>
/// <param name="val">键值</param>
/// <returns>成功返回true,否则返回false</returns>
public static bool iniWrite(string iniPath, string section, string key, string val)
{
long flag = WritePrivateProfileString(section, key, val, iniPath);
return (flag == 0)?(true):(false);
}