我想我已经遇到过这个要求十几次了.但我永远找不到令人满意的解决方案.例如,有一个字符串集合,我想通过一个只允许普通字符串的通道序列化(到磁盘或通过网络).我几乎总是最终使用"分裂"和"加入"与荒谬的分隔符
"::: == - == :::".
像这样:
public static string encode(System.Collections.Generic.List<string> data)
{
return string.Join(" :::==--==::: ", data.ToArray());
}
public static string[] decode(string encoded)
{
return encoded.Split(new string[] { " :::==--==::: " }, StringSplitOptions.None);
}
Run Code Online (Sandbox Code Playgroud)
但这个简单的解决方案显然存在一些缺陷.该字符串不能包含分隔符字符串.因此,编码的字符串不能再重新编码.
AFAIK,全面的解决方案应该包括在编码时转义分隔符并在解码时取消转换.虽然问题听起来很简单,但我相信完整的解决方案可能会占用大量代码.我想知道是否有任何技巧允许我在很少的代码行中构建编码器和解码器?
可以使用在列表<>的.ToArray属性,然后序列化阵列 - 然后可能被转储到磁盘或网络,并与另一端的反序列化重构.
没有太多代码,您可以使用已经在.net框架中测试和编码的序列化技术.
添加引用和usingSystem.Web,然后:
public static string Encode(IEnumerable<string> strings)
{
return string.Join("&", strings.Select(s => HttpUtility.UrlEncode(s)).ToArray());
}
public static IEnumerable<string> Decode(string list)
{
return list.Split('&').Select(s => HttpUtility.UrlDecode(s));
}
Run Code Online (Sandbox Code Playgroud)
大多数语言都有一对实用函数,它们使用Url"百分比"编码,这非常适合在这种情况下重用.
您不需要手动执行此操作。正如其他答案所指出的,有很多内置或其他方式来序列化/反序列化。
但是,如果您确实决定自己完成这项工作,则不需要那么多代码:
public static string CreateDelimitedString(IEnumerable<string> items)
{
StringBuilder sb = new StringBuilder();
foreach (string item in items)
{
sb.Append(item.Replace("\\", "\\\\").Replace(",", "\\,"));
sb.Append(",");
}
return (sb.Length > 0) ? sb.ToString(0, sb.Length - 1) : string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
这将用逗号 ( ) 分隔项目,。任何现有的逗号都将使用反斜杠 ( \) 进行转义,并且任何现有的反斜杠也将被转义。
public static IEnumerable<string> GetItemsFromDelimitedString(string s)
{
bool escaped = false;
StringBuilder sb = new StringBuilder();
foreach (char c in s)
{
if ((c == '\\') && !escaped)
{
escaped = true;
}
else if ((c == ',') && !escaped)
{
yield return sb.ToString();
sb.Length = 0;
}
else
{
sb.Append(c);
escaped = false;
}
}
yield return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)