前言
自己做一個(gè)備份
C#操作文件大概分為以下幾類:
- 配置文件:多數(shù)為 *.ini 文件
- 文本文件:多數(shù)為*.txt 文件
- 二進(jìn)制文件:多數(shù)為避免非法更改
- Office文件:多數(shù)為word、excel文件
- xml文件
1.配置文件
ini為windows常用配置文件,格式如下:
[Section]
Key=Value
我們假設(shè)系統(tǒng)D盤(pán)下有一個(gè)配置文件Config.ini,他的內(nèi)容如下:
[Link]
IP = 192.168.0.1
Port = 1234
[Log]
UserID = admin
PassWord = admin
[TXT]
word = 你好
other = 我是XXX
-
普通讀取ini文件
讀取ini文件有多種方法,僅介紹最常用方法
引入 System.Runtime.InteropServices ,以便引用系統(tǒng)dll文件
引用 kernel32.dll,調(diào)用其方法 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)
{
// 存放讀出數(shù)據(jù)的臨時(shí)變量,這里分配了1024字節(jié)空間,
StringBuilder stringBuilder = new StringBuilder(1024);
// Config.ini中的section,為 Link、Log、TXT
// 1024表示讀1024字節(jié),如數(shù)據(jù)大于1024字節(jié),則后面的會(huì)被舍棄
GetPrivateProfileString(section, key, "", stringBuilder, 1024, "D:/Config.ini");
value = stringBuilder.ToString();
stringBuilder = null;
}
// 獲取Link中的Port數(shù)據(jù),存入變量myPort中
string myPort = "";
GetValue("Link", "Port", out myPort);
// 此時(shí)myPort的值為"1234"
-
獲取ini文件的所有section
如遇到可變的配置文件時(shí),可能無(wú)法事先知道ini文件中含有哪些section,則需先讀取
代碼如下:
using System.Runtime.InteropServices;
// 需要調(diào)用重載
[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();
// 此時(shí)ini_section的值為 "Link" , "Log" , "TXT"
-
獲取某一sections下的所有key值
代碼如下:
using System.Runtime.InteropServices;
// 需要調(diào)用重載
[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");
// 此時(shí)ini_key的值為 "IP" , "Port"
-
普通寫(xiě)ini文件
軟件內(nèi)更改了設(shè)置,通常要寫(xiě)入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");
// 此時(shí)Config.ini文件中IP一行已更改為 IP = 192.168.1.2
-
添加section或key
有時(shí)我們需要添加section或key,來(lái)更新配置
代碼如下:
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");
// 此時(shí)Config.ini文件中會(huì)多出下面的數(shù)據(jù)
// [NewLink]
// newIP = 0.0.0.0
// 如果section已存在,則會(huì)在該section中添加key數(shù)據(jù)
2.文本文件
文本文件通常采用.txt格式存儲(chǔ),讀寫(xiě)文本文件的方法非常多,下面僅介紹其中一種,采用Stream流讀寫(xiě),該方式通用性較好,速度較快
文本文件要特別主意字符的編碼格式
-
讀txt文件
代碼如下:
using System.IO;
// txt默認(rèn)采用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:一次性讀取 需注意,如文件過(guò)大,可能引起意想不到的后果
string r_all_txt = sr.ReadToEnd();
// 使用完畢必須關(guān)閉
sr.Close();
// 如果不再使用,最好釋放掉
sr.Dispose();
-
寫(xiě)txt文件
代碼如下:
using System.IO;
// true表示向文件內(nèi)添加,false表示覆蓋文件
StreamWriter sw = new StreamWriter("D:/1.txt", true, Encoding.UTF8);
sw.Write("要寫(xiě)入這些");
sw.WriteLine("這個(gè)是寫(xiě)入一行");
// 將緩存寫(xiě)入硬盤(pán)
sw.Flush();
// 寫(xiě)完必須關(guān)閉
sw.Close();
// 如果不再使用,最好釋放掉
sw.Dispose();
3. 二進(jìn)制文件
采用ini或txt文件存儲(chǔ)時(shí),用戶可以直接更改文件內(nèi)容,如更改不當(dāng),可能造成系統(tǒng)錯(cuò)誤,因此,一些我們不希望人為更改的數(shù)據(jù),可以采用二進(jìn)制方式存儲(chǔ),同時(shí),二進(jìn)制存儲(chǔ)方式可以加快讀取速度
二進(jìn)制文件名無(wú)后綴要求,此處采用.dat
此處示例采用了字典,其它類型也可以
-
讀二進(jìn)制文件
需先確定二進(jìn)制文件保存的數(shù)據(jù)的數(shù)據(jù)類型,采用相同類型進(jìn)行讀取,否則會(huì)讀取失敗
代碼如下:
// 采用Dictionary字典
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
Dictionary<string, string[]> data = new Dictionary<string, string[]>();
// 打開(kāi).dat文件
FileStream fs = new FileStream("D:/Save.dat", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
// 讀出文件內(nèi)容存入data
data = (Dictionary<string, string[]>)bf.Deserialize(fs);
// 使用完畢必須關(guān)閉文件
fs.Close();
// 采用哈希表
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
Hashtable data = new Hashtable();
// 打開(kāi).dat文件
FileStream fs = new FileStream("D:/Save.dat", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
// 讀出文件內(nèi)容存入data
data = (Hashtable)bf.Deserialize(fs);
// 使用完畢必須關(guān)閉文件
fs.Close();
-
寫(xiě)二進(jìn)制文件
代碼如下:
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
// 創(chuàng)建文件,如原位置已有文件,則覆蓋
FileStream fs = new FileStream("D:/Save.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
// 寫(xiě)入文件,要寫(xiě)入的變量data可以是任意類型,建議采用字典或哈希表格式
bf.Serialize(fs, data);
// 必須要關(guān)閉文件
fs.Close();
4. Office文件
絕大多數(shù)情況下,操作的都是word和excel文件,c#操作此類文件本質(zhì)上是調(diào)用office的COM口,也就是調(diào)用VBA,所以,VBA能夠做到的事情C#都可以做到
-
word操作
待續(xù) -
excel操作
待續(xù)
- xml文件
可參見(jiàn)此文