C# 从.acf/manifest文件读取值
我试图读取的文件的格式如下所示。如何使用c#读取此文件以提取属性值?有我可以利用的库吗C# 从.acf/manifest文件读取值,c#,manifest,steam,C#,Manifest,Steam,我试图读取的文件的格式如下所示。如何使用c#读取此文件以提取属性值?有我可以利用的库吗 "AppState" { "appid" "244210" "Universe" "1" "name" "Assetto Corsa" "StateFlags" "4" "installdir" "assettocorsa" "LastUpdated" "1469806809" "UpdateResult" "0" "SizeOnD
"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"
}
}
所以我不知道你是否还需要它,但我自己写的。 这是我的密码 在我的测试中,它工作得非常好
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!");
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
名称空间Steam\u acf\u文件\u读取器
{
AcfReader类
{
公共字符串文件位置{get;private set;}
公共AcfReader(字符串文件位置)
{
if(File.Exists(FileLocation))
this.FileLocation=FileLocation;
其他的
抛出新的FileNotFoundException(“错误”,FileLocation);
}
公共bool CheckIntegrity()
{
字符串内容=File.ReadAllText(文件位置);
int quote=Content.Count(x=>x==“”);
int-braceleft=Content.Count(x=>x='{');
int-braceright=Content.Count(x=>x=''}');
返回((括号左==括号右)&&(引号%2==0));
}
公共ACF_结构ACFFileToStruct()
{
返回acffieltostruct(File.ReadAllText(FileLocation));
}
私有ACF_结构ACFFileToStruct(字符串区域读入)
{
ACF_Struct ACF=新的ACF_Struct();
int LengthOfRegion=区域读取长度;
int CurrentPos=0;
while(长度区域>当前位置)
{
int FirstItemStart=RegionToReadIn.IndexOf(“”,CurrentPos);
如果(FirstItemStart==-1)
打破
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);
如果(SecondItemStartBraceleft==-1 | | SecondItemStartQuote打开项)
返回i;
}
}
抛出新异常(“结束字符不足!”);
}
}
}
我知道我可以去掉空白,并在引号之间找到值,但这相当不容易。