C#:将CookieContainer写入磁盘并重新加载以供使用

C#:将CookieContainer写入磁盘并重新加载以供使用,c#,file-io,cookies,httpwebrequest,cookiecontainer,C#,File Io,Cookies,Httpwebrequest,Cookiecontainer,我从名为CookieJar的HttpWebRequest/HttpWebResponse会话中提取了一个名为CookieJar的CookieContainer。我希望我的应用程序在两次运行之间存储cookie,这样在程序的一次运行中收集的cookie也将用于下一次运行 我认为这样做的方法是以某种方式将CookieContainer的内容写入磁盘。我的问题是: 如何将CookieContainer写入磁盘?是否有内置的功能,或者,如果没有,人们采取了什么方法?有什么课程可以简化这一点吗 将Coo

我从名为CookieJar的HttpWebRequest/HttpWebResponse会话中提取了一个名为CookieJar的CookieContainer。我希望我的应用程序在两次运行之间存储cookie,这样在程序的一次运行中收集的cookie也将用于下一次运行

我认为这样做的方法是以某种方式将CookieContainer的内容写入磁盘。我的问题是:

  • 如何将CookieContainer写入磁盘?是否有内置的功能,或者,如果没有,人们采取了什么方法?有什么课程可以简化这一点吗
  • 将CookieContainer写入磁盘后,如何将其重新加载以供使用

更新:第一个答案建议对
CookieContainer
进行序列化。但是,我不太熟悉如何序列化和反序列化这些复杂对象。您能提供一些示例代码吗?建议使用
SOAPFormatter

我没有尝试过,但它具有可序列化的属性,因此可以使用.net二进制序列化(例如SOAPFormatter)进行[反]序列化

这是您要的代码片段

var formatter = new SoapFormatter();
string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cookies.dat"); 

using (Stream s = File.Create (file))
    formatter.Serialize(s, cookies);                            
...
CookieContainer retrievedCookies = null;
using (Stream s = File.OpenRead (file))
    retrievedCookies = (CookieContainer) formatter.Deserialize(s);
看看msdn,SoapFormatter现在似乎在.NET3.5中不受欢迎,它建议您使用Binaryformatter。在过去,我发现SoapFormatter很有用,因为文件可读,这有助于在反序列化失败时进行诊断!即使在程序集版本中,这些格式化程序对版本更改也很敏感(因此,如果使用一个版本的框架反序列化升级框架,那么它可能不会反序列化,也不确定),但如果出现问题,可以使用Binder属性解决此问题。我相信它们主要是为短期的持久性/远程处理而设计的,但是在这里它们可能对您来说已经足够好了

新的DataContractSerializer似乎无法与之配合使用,因此已过时


另一种方法是编写一个CookieContainerData类,用XmlSerializer进行[反]序列化,并手动在该类和CookieContainer之间进行转换。

这个问题困扰了我很久,我找不到任何有效的方法。我算出了,所以把这些信息发布到世界上

使用BinaryFormatter回答:

    public static void WriteCookiesToDisk(string file, CookieContainer cookieJar)
    {
        using(Stream stream = File.Create(file))
        {
            try {
                Console.Out.Write("Writing cookies to disk... ");
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, cookieJar);
                Console.Out.WriteLine("Done.");
            } catch(Exception e) { 
                Console.Out.WriteLine("Problem writing cookies to disk: " + e.GetType()); 
            }
        }
    }   

    public static CookieContainer ReadCookiesFromDisk(string file)
    {

        try {
            using(Stream stream = File.Open(file, FileMode.Open))
            {
                Console.Out.Write("Reading cookies from disk... ");
                BinaryFormatter formatter = new BinaryFormatter();
                Console.Out.WriteLine("Done.");
                return (CookieContainer)formatter.Deserialize(stream);
            }
        } catch(Exception e) { 
            Console.Out.WriteLine("Problem reading cookies from disk: " + e.GetType()); 
            return new CookieContainer(); 
        }
    }

有文本格式的cookie是很有趣的。除了可以用来写磁盘,它还可以用于其他目的

为我工作

使用
LoadCookiesFromFile
SaveCookiesToFile
函数分别将cookies加载和写入磁盘

或者使用
GetCookies
SetCookies
函数执行相同的操作,但将其作为字符串进行操作

CookieContainer cookieContainer = new CookieContainer();

void LoadCookiesFromFile(string path)
{
    SetCookies(cookieContainer, File.ReadAllText(path));
}

void SaveCookiesToFile(string path)
{
    File.WriteAllText(path, GetCookies(cookieContainer));
}

string GetCookies(CookieContainer cookieContainer)
{
    using (MemoryStream stream = new MemoryStream())
    {
        new BinaryFormatter().Serialize(stream, cookieContainer);
        var bytes = new byte[stream.Length];
        stream.Position = 0;
        stream.Read(bytes, 0, bytes.Length);
        return Convert.ToBase64String(bytes);
    }
}

void SetCookies(CookieContainer cookieContainer, string cookieText)
{
    try
    {
        var bytes = Convert.FromBase64String(cookieText);
        using (MemoryStream stream = new MemoryStream(bytes))
        {
            cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
        }
    }
    catch
    {
        //Ignore if the string is not valid.
    }
}

我对序列化不太了解,所以你能提供一些示例代码吗?反正我可以用SQL而不是文件来存储?我不会称之为“文本格式的cookies”。它是“二进制数据作为base64”。我认为Cookie本身就是文本,所以如果您编写自己的基于文本的序列化程序,就可以将Cookie存储为人类可读的文本——可以是JSON,也可以是缩进文本部分。