通过StringBuilder将字节顺序标记添加到字符串

时间:2014-03-10 17:07:09

标签: c# utf-8 stringbuilder byte-order-mark

如何向StringBuilder添加字节顺序标记? (我必须将一个字符串传递给另一个将其保存为文件的方法,但我无法修改该方法。)

我试过了:

var sb = new StringBuilder();
sb.Append('\xEF');
sb.Append('\xBB');
sb.Append('\xBF');

但是当我用十六进制编辑器查看它时,它会添加以下序列: C3 AF C2 BB C2 BF

字符串很大,所以不用来回转换为字节数组就可以了。

修改 在评论中提出问题后澄清。我必须将字符串传递给另一个接受字符串的方法,并在Azure Blob存储上创建它的文件。我无法修改其他方法。

4 个答案:

答案 0 :(得分:11)

两个选项:

  1. 根本不要在文本中包含字节顺序标记...而是使用自动包含它的编码
  2. StringBuilder中将作为字符包含在内:

    sb.Append('\uFEFF'); // U+FEFF is the byte-order mark character
    
  3. 就个人而言,我通常会采用第一种方法,但“我无法修改该方法”表明它可能不是您的选择。

答案 1 :(得分:7)

字节顺序标记用于通知读者文件具有特定编码的文件。因此,您只需要在实际文件中使用字节顺序标记(BOM)。如果要在正在编写的文本文件中包含BOM,只需使用StreamWriter写入文件即可。例如:

using(var writer = new StreamWriter(stream, System.Text.Encoding.UTF8))
{
    writer.Write(sb.ToString);
}

如果您不想要带有UTF-8的BOM:

using(var writer = new StreamWriter(stream))
{
    writer.Write(sb.ToString());
}

或者如果您需要不同的BOM:

using(var writer = new StreamWriter(stream, System.Text.Encoding.UTF16))
{
    writer.Write(sb.ToString);
}

更新

如果您希望从BOM的实现细节或特定编码的BOM(即可能在运行时或部署后更改)中进行耦合,但仍希望传递BOM标记的字符串,则可以执行以下操作: (假设是.NET 4.5):

var stream = new MemoryStream();
var encoding = Encoding.UTF8; // TODO: configurize this, if necessary
using(var writer = new StreamWriter(stream, encoding, 1024, true))
{
    writer.Write(sb.ToString());
}
CantModifyButMustUseThis(encoding.GetString(stream.ToArray());

答案 2 :(得分:1)

IIRC(我不确定),当您使用相关的Unicode编码器之一转换为字节时,会添加BOM。我相信some of those's constructors采取控制是否添加BOM的布尔值。

答案 3 :(得分:0)

我在ASP.NET核心中使用了此代码,很好!!它有效

 [HttpGet("GetCsv")]
    public async Task<IActionResult> GetCsv() {
        
        var cc = new CsvConfiguration(new System.Globalization.CultureInfo("en-US"));
        var entity = await _service.AdminPanelList();
        using (var ms = new MemoryStream()) {
            using (var sw = new StreamWriter(stream: ms, encoding: new UTF8Encoding(true))) {
                using (var cw = new CsvWriter(sw, cc)) {

                    var bom = '\uFEFF'.ToString();
                    byte[] bomArray = Encoding.UTF8.GetBytes(bom);
                    
                    ms.Write(bomArray);
                    cw.WriteRecords(entity);
                }

                var finalArray = ms.ToArray();
                



                var result = File(finalArray, "text/csv", $"PersonExport.csv");
                    

                return result;
            }
        }
    }