我正在尝试阅读的文件以下面的格式显示。如何使用c#读取此文件以提取属性值?有没有我可以利用的图书馆?
"AppState"
{
"appid" "244210"
"Universe" "1"
"name" "Assetto Corsa"
"StateFlags" "4"
"installdir" "assettocorsa"
"LastUpdated" "1469806809"
"UpdateResult" "0"
"SizeOnDisk" "23498042501"
"buildid" "1251512"
"LastOwner" "76561198018619129"
"BytesToDownload" "11541616"
"BytesDownloaded" "11541616"
"AutoUpdateBehavior" "0"
"AllowOtherDownloadsWhileRunning" "0"
"UserConfig"
{
"language" "english"
}
"MountedDepots"
{
"228983" "8124929965194586177"
"228984" "3215975441341951460"
"228985" "5758075142805954616"
"228990" "1829726630299308803"
"229002" "7260605429366465749"
"244211" "3837890045968273966"
}
"InstallScripts"
{
"0" "_CommonRedist\\vcredist\\2010\\installscript.vdf"
"1" "_CommonRedist\\vcredist\\2012\\installscript.vdf"
"2" "_CommonRedist\\vcredist\\2013\\installscript.vdf"
"3" "_CommonRedist\\DirectX\\Jun2010\\installscript.vdf"
"4" "_CommonRedist\\DotNet\\4.0\\installscript.vdf"
}
}
答案 0 :(得分:1)
所以我不知道你是否还需要它,但我自己写了。 这是我的代码。
在我的测试中它完美无缺。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Steam_acf_File_Reader
{
class AcfReader
{
public string FileLocation { get; private set; }
public AcfReader(string FileLocation)
{
if (File.Exists(FileLocation))
this.FileLocation = FileLocation;
else
throw new FileNotFoundException("Error", FileLocation);
}
public bool CheckIntegrity()
{
string Content = File.ReadAllText(FileLocation);
int quote = Content.Count(x => x == '"');
int braceleft = Content.Count(x => x == '{');
int braceright = Content.Count(x => x == '}');
return ((braceleft == braceright) && (quote % 2 == 0));
}
public ACF_Struct ACFFileToStruct()
{
return ACFFileToStruct(File.ReadAllText(FileLocation));
}
private ACF_Struct ACFFileToStruct(string RegionToReadIn)
{
ACF_Struct ACF = new ACF_Struct();
int LengthOfRegion = RegionToReadIn.Length;
int CurrentPos = 0;
while (LengthOfRegion > CurrentPos)
{
int FirstItemStart = RegionToReadIn.IndexOf('"', CurrentPos);
if (FirstItemStart == -1)
break;
int FirstItemEnd = RegionToReadIn.IndexOf('"', FirstItemStart + 1);
CurrentPos = FirstItemEnd + 1;
string FirstItem = RegionToReadIn.Substring(FirstItemStart + 1, FirstItemEnd - FirstItemStart - 1);
int SecondItemStartQuote = RegionToReadIn.IndexOf('"', CurrentPos);
int SecondItemStartBraceleft = RegionToReadIn.IndexOf('{', CurrentPos);
if (SecondItemStartBraceleft == -1 || SecondItemStartQuote < SecondItemStartBraceleft)
{
int SecondItemEndQuote = RegionToReadIn.IndexOf('"', SecondItemStartQuote + 1);
string SecondItem = RegionToReadIn.Substring(SecondItemStartQuote + 1, SecondItemEndQuote - SecondItemStartQuote - 1);
CurrentPos = SecondItemEndQuote + 1;
ACF.SubItems.Add(FirstItem, SecondItem);
}
else
{
int SecondItemEndBraceright = RegionToReadIn.NextEndOf('{', '}', SecondItemStartBraceleft + 1);
ACF_Struct ACFS = ACFFileToStruct(RegionToReadIn.Substring(SecondItemStartBraceleft + 1, SecondItemEndBraceright - SecondItemStartBraceleft - 1));
CurrentPos = SecondItemEndBraceright + 1;
ACF.SubACF.Add(FirstItem, ACFS);
}
}
return ACF;
}
}
class ACF_Struct
{
public Dictionary<string, ACF_Struct> SubACF { get; private set; }
public Dictionary<string, string> SubItems { get; private set; }
public ACF_Struct()
{
SubACF = new Dictionary<string, ACF_Struct>();
SubItems = new Dictionary<string, string>();
}
public void WriteToFile(string File)
{
}
public override string ToString()
{
return ToString(0);
}
private string ToString(int Depth)
{
StringBuilder SB = new StringBuilder();
foreach (KeyValuePair<string, string> item in SubItems)
{
SB.Append('\t', Depth);
SB.AppendFormat("\"{0}\"\t\t\"{1}\"\r\n", item.Key, item.Value);
}
foreach (KeyValuePair<string, ACF_Struct> item in SubACF)
{
SB.Append('\t', Depth);
SB.AppendFormat("\"{0}\"\n", item.Key);
SB.Append('\t', Depth);
SB.AppendLine("{");
SB.Append(item.Value.ToString(Depth + 1));
SB.Append('\t', Depth);
SB.AppendLine("}");
}
return SB.ToString();
}
}
static class Extension
{
public static int NextEndOf(this string str, char Open, char Close, int startIndex)
{
if (Open == Close)
throw new Exception("\"Open\" and \"Close\" char are equivalent!");
int OpenItem = 0;
int CloseItem = 0;
for (int i = startIndex; i < str.Length; i++)
{
if (str[i] == Open)
{
OpenItem++;
}
if (str[i] == Close)
{
CloseItem++;
if (CloseItem > OpenItem)
return i;
}
}
throw new Exception("Not enough closing characters!");
}
}
}