前言
自己做一个备份
C#操作文件大概分为以下几类:
- 配置文件:多数为 *.ini 文件
- 文本文件:多数为*.txt 文件
- 二进制文件:多数为避免非法更改
- Office文件:多数为word、excel文件
- xml文件
1.配置文件
ini为windows常用配置文件,格式如下:
[Section]
Key=Value
我们假设系统D盘下有一个配置文件Config.ini,他的内容如下:
[Link]
IP = 192.168.0.1
Port = 1234
[Log]
UserID = admin
PassWord = admin
[TXT]
word = 你好
other = 我是XXX
-
普通读取ini文件
读取ini文件有多种方法,仅介绍最常用方法
引入 System.Runtime.InteropServices ,以便引用系统dll文件
引用 kernel32.dll,调用其方法 GetPrivateProfileString即可
代码如下:
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder returnvalue, int buffersize, string filepath);
public void GetValue(string section, string key, out string value)
{
// 存放读出数据的临时变量,这里分配了1024字节空间,
StringBuilder stringBuilder = new StringBuilder(1024);
// Config.ini中的section,为 Link、Log、TXT
// 1024表示读1024字节,如数据大于1024字节,则后面的会被舍弃
GetPrivateProfileString(section, key, "", stringBuilder, 1024, "D:/Config.ini");
value = stringBuilder.ToString();
stringBuilder = null;
}
// 获取Link中的Port数据,存入变量myPort中
string myPort = "";
GetValue("Link", "Port", out myPort);
// 此时myPort的值为"1234"
-
获取ini文件的所有section
如遇到可变的配置文件时,可能无法事先知道ini文件中含有哪些section,则需先读取
代码如下:
using System.Runtime.InteropServices;
// 需要调用重载
[DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
private static extern uint GetPrivateProfileStringA(string section, string key,
string def, Byte[] retVal, int size, string filePath);
public static List<string> ReadSections()
{
List<string> result = new List<string>();
Byte[] buf = new Byte[65536];
uint len = GetPrivateProfileStringA(null, null, null, buf, buf.Length, "D:/Config.ini");
int j = 0;
for (int i = 0; i < len; i++)
if (buf[i] == 0)
{
result.Add(Encoding.Default.GetString(buf, j, i - j));
j = i + 1;
}
return result;
}
// 获取sections,存入list
List<string> ini_section = ReadSections();
// 此时ini_section的值为 "Link" , "Log" , "TXT"
-
获取某一sections下的所有key值
代码如下:
using System.Runtime.InteropServices;
// 需要调用重载
[DllImport("kernel32", EntryPoint = "GetPrivateProfileString")]
private static extern uint GetPrivateProfileStringA(string section, string key,
string def, Byte[] retVal, int size, string filePath);
public static List<string> ReadKeys(string SectionName)
{
List<string> result = new List<string>();
Byte[] buf = new Byte[65536];
uint len = GetPrivateProfileStringA(SectionName, null, null, buf, buf.Length, "D:/Config.ini");
int j = 0;
for (int i = 0; i < len; i++)
if (buf[i] == 0)
{
result.Add(Encoding.Default.GetString(buf, j, i - j));
j = i + 1;
}
return result;
}
// 获取Link下所有的key值,存入list
List<string> ini_key = ReadKeys("Link");
// 此时ini_key的值为 "IP" , "Port"
-
普通写ini文件
软件内更改了设置,通常要写入ini文件中,比如更改了IP为192.168.1.2
代码如下:
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
private static extern long WritePrivateProfileString(string section, string key, string value, string filepath);
WritePrivateProfileString("Link", "IP", "192.168.1.2", "D:/Config.ini");
// 此时Config.ini文件中IP一行已更改为 IP = 192.168.1.2
-
添加section或key
有时我们需要添加section或key,来更新配置
代码如下:
using System.Runtime.InteropServices;
[DllImport("Kernel32.dll")]
public static extern long WritePrivateProfileSection(string strAppName, string strkeyandvalue, string strFileName);
WritePrivateProfileSection("NewLink", "newIP = 0.0.0.0", "D:/Config.ini");
// 此时Config.ini文件中会多出下面的数据
// [NewLink]
// newIP = 0.0.0.0
// 如果section已存在,则会在该section中添加key数据
2.文本文件
文本文件通常采用.txt格式存储,读写文本文件的方法非常多,下面仅介绍其中一种,采用Stream流读写,该方式通用性较好,速度较快
文本文件要特别主意字符的编码格式
-
读txt文件
代码如下:
using System.IO;
// txt默认采用ANSI字符,而非utf8,这里演示用的是utf8
StreamReader sr = new StreamReader(path, Encoding.UTF8);
// 方式1:一行一行读取
List<string> r_txt = new List<string>();
while (sr.Peek() != -1)
{
r_txt.Add(sr.ReadLine());
}
// 方式2:一次性读取 需注意,如文件过大,可能引起意想不到的后果
string r_all_txt = sr.ReadToEnd();
// 使用完毕必须关闭
sr.Close();
// 如果不再使用,最好释放掉
sr.Dispose();
-
写txt文件
代码如下:
using System.IO;
// true表示向文件内添加,false表示覆盖文件
StreamWriter sw = new StreamWriter("D:/1.txt", true, Encoding.UTF8);
sw.Write("要写入这些");
sw.WriteLine("这个是写入一行");
// 将缓存写入硬盘
sw.Flush();
// 写完必须关闭
sw.Close();
// 如果不再使用,最好释放掉
sw.Dispose();
3. 二进制文件
采用ini或txt文件存储时,用户可以直接更改文件内容,如更改不当,可能造成系统错误,因此,一些我们不希望人为更改的数据,可以采用二进制方式存储,同时,二进制存储方式可以加快读取速度
二进制文件名无后缀要求,此处采用.dat
此处示例采用了字典,其它类型也可以
-
读二进制文件
需先确定二进制文件保存的数据的数据类型,采用相同类型进行读取,否则会读取失败
代码如下:
// 采用Dictionary字典
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
Dictionary<string, string[]> data = new Dictionary<string, string[]>();
// 打开.dat文件
FileStream fs = new FileStream("D:/Save.dat", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
// 读出文件内容存入data
data = (Dictionary<string, string[]>)bf.Deserialize(fs);
// 使用完毕必须关闭文件
fs.Close();
// 采用哈希表
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
Hashtable data = new Hashtable();
// 打开.dat文件
FileStream fs = new FileStream("D:/Save.dat", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
// 读出文件内容存入data
data = (Hashtable)bf.Deserialize(fs);
// 使用完毕必须关闭文件
fs.Close();
-
写二进制文件
代码如下:
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
// 创建文件,如原位置已有文件,则覆盖
FileStream fs = new FileStream("D:/Save.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
// 写入文件,要写入的变量data可以是任意类型,建议采用字典或哈希表格式
bf.Serialize(fs, data);
// 必须要关闭文件
fs.Close();
4. Office文件
绝大多数情况下,操作的都是word和excel文件,c#操作此类文件本质上是调用office的COM口,也就是调用VBA,所以,VBA能够做到的事情C#都可以做到
-
word操作
待续 -
excel操作
待续
- xml文件
可参见此文
