C# 按字节截断字符串

trim string to the specified number of bytes

把字符串转成字节数组后,截断至特定长度时,可能会导致尾部乱码,可以使用以下方法进行安全截断

   

@@@code

foreach (var encode in

new Encoding[]{

Encoding.UTF8,

Encoding.Unicode,

Encoding.Default

}

)

{

Console.WriteLine($"-----------------\r\n{encode.EncodingName}");

byte[] bs = encode.GetBytes(ss);

for (int i = 1; i < bs.Length; i++)

{

byte[] result = trimStringBytes(ss, encode, i);

Console.WriteLine($"截断为{i}个字节时,有效字节数:{result.Length},完整的字符串是:{encode.GetString(result)}");

   

}

}

   

/// <summary>

/// 截断字符串字节数组

/// </summary>

/// <param name="ss"></param>

/// <param name="encoding"></param>

/// <param name="len">需要得到的长度</param>

/// <param name="bs">处理后的数组</param>

/// <returns></returns>

public static byte[] trimStringBytes( string ss, System.Text.Encoding encoding, int len)

{

if (len == 0)

{

return new byte[0];

}

byte[] bs = encoding.GetBytes(ss);

if (len >= bs.Length)

{

Array.Resize(ref bs, len);

return bs;

}

char[] cc = ss.ToCharArray();

int c = encoding.GetCharCount(bs, 0, len); //涉及了C个字符

int m = encoding.GetByteCount(cc, 0, c); //计算C个字符串应当使用的字节数

// 如果当前截断导致字符串不完整(小于m),减1

if (m == len)

{

Array.Resize(ref bs, len);

return bs;

}

else

{

Array.Resize(ref bs, encoding.GetByteCount(cc, 0, c - 1));

return bs;

}

}

   

   

@@#

   

输出结果

Unicode (UTF-8)

截断为1个字节时,有效字节数:0,完整的字符串是:

截断为2个字节时,有效字节数:0,完整的字符串是:

截断为3个字节时,有效字节数:3,完整的字符串是:单

截断为4个字节时,有效字节数:3,完整的字符串是:单

截断为5个字节时,有效字节数:3,完整的字符串是:单

截断为6个字节时,有效字节数:6,完整的字符串是:单位

截断为7个字节时,有效字节数:7,完整的字符串是:单位c

截断为8个字节时,有效字节数:8,完整的字符串是:单位cm

截断为9个字节时,有效字节数:8,完整的字符串是:单位cm

截断为10个字节时,有效字节数:8,完整的字符串是:单位cm

截断为11个字节时,有效字节数:11,完整的字符串是:单位cm!

截断为12个字节时,有效字节数:12,完整的字符串是:单位cm!1

截断为13个字节时,有效字节数:13,完整的字符串是:单位cm!12

-----------------

Unicode

截断为1个字节时,有效字节数:0,完整的字符串是:

截断为2个字节时,有效字节数:2,完整的字符串是:单

截断为3个字节时,有效字节数:2,完整的字符串是:单

截断为4个字节时,有效字节数:4,完整的字符串是:单位

截断为5个字节时,有效字节数:4,完整的字符串是:单位

截断为6个字节时,有效字节数:6,完整的字符串是:单位c

截断为7个字节时,有效字节数:6,完整的字符串是:单位c

截断为8个字节时,有效字节数:8,完整的字符串是:单位cm

截断为9个字节时,有效字节数:8,完整的字符串是:单位cm

截断为10个字节时,有效字节数:10,完整的字符串是:单位cm!

截断为11个字节时,有效字节数:10,完整的字符串是:单位cm!

截断为12个字节时,有效字节数:12,完整的字符串是:单位cm!1

截断为13个字节时,有效字节数:12,完整的字符串是:单位cm!1

截断为14个字节时,有效字节数:14,完整的字符串是:单位cm!12

截断为15个字节时,有效字节数:14,完整的字符串是:单位cm!12

-----------------

简体中文(GB2312)

截断为1个字节时,有效字节数:0,完整的字符串是:

截断为2个字节时,有效字节数:2,完整的字符串是:单

截断为3个字节时,有效字节数:2,完整的字符串是:单

截断为4个字节时,有效字节数:4,完整的字符串是:单位

截断为5个字节时,有效字节数:5,完整的字符串是:单位c

截断为6个字节时,有效字节数:6,完整的字符串是:单位cm

截断为7个字节时,有效字节数:6,完整的字符串是:单位cm

截断为8个字节时,有效字节数:8,完整的字符串是:单位cm!

截断为9个字节时,有效字节数:9,完整的字符串是:单位cm!1

截断为10个字节时,有效字节数:10,完整的字符串是:单位cm!12

   

 

 

Java 中的写法

@@@code

public static byte[] trimStringBytes(String ss, Charset encoding, int len) {
if (len == 0) {
return new byte[0];
}
ByteBuffer bs = encoding.encode(ss);
if (len >= bs.remaining()) {
byte[] result = new byte[len];
bs.get(result, 0, bs.remaining());
return result;
}
bs.limit(len);//
限制可读长度
CharBuffer cb = CharBuffer.allocate(len);
CharsetDecoder cd = encoding.newDecoder();
// Ignore an incomplete character
cd.onMalformedInput(CodingErrorAction.IGNORE);
cd.decode(bs, cb, true);
cd.flush(cb);
String s = new String(cb.array(), 0, cb.position());
ByteBuffer nf = encoding.encode(s);
byte[] result = new byte[nf.remaining()];
nf.get(result);
return result;
}

 

@@#

posted @ 2022-06-23 22:46  秦秋随  阅读(533)  评论(0编辑  收藏  举报