在C#中使用分隔符连接字节数组

3

我需要类似于String.Join(separator_string, list_of_strings)的东西,但是针对字节数组。

我需要它,因为我正在实现一个文件格式编写器,规范要求:

"每个注释必须以UTF-8编码,并用ASCII字节20分隔。"

然后我需要这样的东西:

byte separator = 20;
List<byte[]> encoded_annotations;

joined_byte_array = Something.Join(separator, encoded_annotations);

3
听起来你只需使用\u0014将所有字符串连接起来,最后使用UTF-8将整个字符串转换为字节数组。 - Jon Skeet
1
@JonSkeet 我已经准备好接受这样的建议,最终可能会实现它。但无论如何,我想保留我的问题:如何使用其他字节数组作为分隔符连接字节数组,对于任意不可转换为/自字符串的数组? - heltonbiker
你确定你的 20 是/不是一个空格 / " "?只需构建您的注释字符串,用空格分隔作为常规 C# 字符串,并将其写入 UTF8。 - DrKoch
@DrKoch,规范还提到了字节210,分别用作时间戳注释列表(这是要序列化的完整结构)的分隔符。顺便说一下,根据ASCII表,空格字符是字节32,对吧? - heltonbiker
3个回答

3

我不相信这个功能是内置的,但编写起来非常简单。下面是一个通用版本,但你可以轻松地让它只操作字节数组。

public static T[] Join<T>(T separator, IEnumerable<T[]> arrays)
{
    // Make sure we only iterate over arrays once
    List<T[]> list = arrays.ToList();
    if (list.Count == 0)
    {
        return new T[0];
    }
    int size = list.Sum(x => x.Length) + list.Count - 1;
    T[] ret = new T[size];
    int index = 0;
    bool first = true;
    foreach (T[] array in list)
    {
        if (!first)
        {
            ret[index++] = separator;
        }
        Array.Copy(array, 0, ret, index, array.Length);
        index += array.Length;
        first = false;
    }
    return ret;
}

你介意给出对我发布的另一种答案的看法吗?谢谢! - heltonbiker

1
我最终使用了这个方法,根据我的具体情况进行了调整,将分隔符设置为一个单字节(而不是一个大小为一的数组),但是这个通用方法也适用于由字节数组组成的分隔符:
public byte[] ArrayJoin(byte separator, List<byte[]> arrays)
{
    using (MemoryStream result = new MemoryStream())
    {
        byte[] first = arrays.First();
        result.Write(first, 0, first.Length);

        foreach (var array in arrays.Skip(1))
        {
            result.WriteByte(separator);
            result.Write(array, 0, array.Length);
        }

        return result.ToArray();
    }
}

是的,那个可以正常工作 - 在调整大小方面稍微不太高效,但没问题... - Jon Skeet
@JonSkeet,关于调整大小的低效率是我想了解的血腥细节。再次感谢! - heltonbiker

1

您只需要指定加入命令所需的类型即可。

String.join<byte>(separator_string, list_of_strings);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接