byte[] 解析、转码二三事
1.先从byte 说起, byte 范围为 0~255 的整数,这个区间是在 int 范围中,所以 当byte 转为 int 时,则为小范围转大范围,隐式转换可以直接转换,反过来就是显式转换 需要Convert 下
byte a = ;
byte b = ;
//正整数+正整数 可以赋值给byte(正常理解应该是,整型转为byte型,特例)
byte c = + ;
// byte类型+整数 为 int类型
byte d = Convert.ToByte(a + );
// byte类型 + byte类型 为 int类型
byte e = Convert.ToByte(a + b);![]()
//将int32转换为字节数组,防止数据丢失,如右图
byte[] bytes = BitConverter.GetBytes(258);
//此外Byte[] 与 String 转换
byte[] bts = System.Text.Encoding.Default.GetBytes(str);
string str = System.Text.Encoding.Default.GetString(bts);
2.对于bytes数组来说,其实也没啥太大的差别,记住一些常用的操作即可,比如,合并,截取,拼接
byte[] bts1 = new byte[];
bts1[] = ;
bts1[] = ; byte[] bts2 = new byte[];
bts2[] = ;
bts2[] = ;
bts2[] = ; //累加,值为 10,12,0,0,0,0,0,0,0,14,15,16,0,0,0
bts1 = bts1.Concat(bts2).ToArray(); //当一个byte[] 数组特别大的时候,想截取其中的有效值(比如长度1000,从600以后都是空值0)
bts1 = bts1.Skip().Take().ToArray(); //截取有效值后拼接
bts1 = bts1.Skip().Take().ToArray().Concat(bts2.Skip().Take().ToArray()).ToArray();
3. 实际项目中往往涉及到一些繁复的转换,诸如,byte[]、image、bitmap 、16进制之间的相互转换
#region 图片格式转byte[]
public byte[] ImageToBytes(Image image)
{
ImageFormat format = image.RawFormat;
using (MemoryStream ms = new MemoryStream())
{
//直接转会出现问题,中间用Bitmap包裹一层
Bitmap t = new Bitmap(image);
t.Save(ms, format);
return ms.ToArray();
}
}
#endregion
#region byte[] 转图片
public Image convertImg(byte[] datas)
{
MemoryStream ms = new MemoryStream(datas);
Image img = Image.FromStream(ms, true);
//流用完要及时关闭
ms.Close();
return img;
}
#endregion
#region bitmap 转byte数组
public static byte[] BitmapToBytes(Bitmap Bitmap)
{
MemoryStream mstream = new MemoryStream();
Bitmap.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] byData = new Byte[mstream.Length];
mstream.Position = ;
mstream.Read(byData, , byData.Length); mstream.Close();
return byData;
}
解析字符串时,比较简单,但是需要注意的是,如果是单纯的byte数组没问题,如果byte[] 中含有字符串,图片等,直接解析肯定是乱码,一定要先根据长度截取想对应部分后分别再去解析
//将byte数组 转换为string,中文字符时使用 UTF-8
string middataLen = Encoding.Default.GetString(bt1s, , bts1.Length);
//参数为byte[] bytes, int index, int count) 三个参数为解析指定长度的数组,只有bytes一个参数时为解析全部
string middataLen1 = Encoding.Default.GetString(bt1s);
现有一复杂字节数组,其中含有string、图片, 如果需将此字节数组存入本地txt文件中,常规方式肯定会出现乱码,实际上往往是先将数组转换为16进制,然后在写入到流文件中,需要的时候再去解析该文件,转成byte[] 数组再进行操作
#region byte[]数组转16进制文件
private static void WriteToTxt(byte[] bytContents,string strpath)
{
int length = bytContents.Length;
StringBuilder builder = new StringBuilder(length * );
foreach (byte value in bytContents)
{
builder.AppendFormat("{0:X} ", value);
}
System.IO.StreamWriter sw = new System.IO.StreamWriter(strpath, false, System.Text.Encoding.Default);
sw.Write(builder.ToString());
sw.Close();
}
#endregion
#region (16进制)文件 转byte[]
/// <summary>
/// </summary>
/// <param name="strFile">文件路径</param>
/// <returns></returns>
public static byte[] Read(string strFile)
{
StreamReader sr = new StreamReader(strFile, Encoding.Default);
string strContent = sr.ReadToEnd();
sr.Close();
string[] arry = strContent.Split(' ');
arry = arry.Skip().Take(arry.Length - ).ToArray();
List<byte> lstRet = new List<byte>();
foreach (string s in arry)
{
lstRet.Add(Convert.ToByte(s, ));
}
return lstRet.ToArray();
}
#endregion
以上是关于byte[] 的基本操作,基本满足常规要求,下面来说说TCP/IP接口,调用此接口,接收数据,然后解析。
//创建连接参数对象
private IPAddress serverIP = IPAddress.Parse("127.0.00.1");
private IPEndPoint serverFullAddr;
private Socket sock; private void btn_conn_Click(object sender, EventArgs e)
{ btn_conn.Enabled = false;
serverIP = IPAddress.Parse(tbxIP.Text);
try
{
serverFullAddr = new IPEndPoint(serverIP, int.Parse(tbxPort.Text));//设置IP,端口
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//指定本地主机地址和端口号
sock.Connect(serverFullAddr);
//发送数据
//sock.Send(bytes);
//接收数据
byte[] conn_bts = new byte[];
int conn_Len = sock.Receive(conn_bts);
var conn_mess = Encoding.Default.GetString(conn_bts, , conn_Len);
//判断是否连接成功
//if(conn_mess)
//
//
sock.Close(); }
catch (Exception ee)
{
btn_conn.Enabled = true;
lab_err.Text = "连接服务器失败。。。请仔细检查服务器是否开启" + ee.Message;
} } //关闭连接
private void btn_close_Click(object sender, EventArgs e)
{
lab_err.Text = "";
sock.Close();
btn_conn.Enabled = true;
btn_Send.Enabled = false;
}
调用TCP/IP 接口的时候,使用Sock的Receive() 方法去接接收Stream流数据时,如果一次未接收完,第二次接收是从上次结束时的末尾开始接收
byte[] bytes1 = new byte[];
//byte[]数组一旦定义长度,如果接口总数据长度小于500,则bytes1中有效长度为Row,剩下的索引值为0
int row = sock.Receive(bytes1); //等价于 sock.Receive(bytes1, 500, 0);
//当接口返回数据总长度大于500的时候,比如为800,再次使用Receive(),是从索引为500的位置开始接收
//如果想把余下800-500=300 一次性接收完,则为
byte[] bytes2 = new byte[-row];
int count = sock.Receive(bytes2);
//有时候数据很长,一次或者两次无法接受完,这时需要写一个循环接收,两种思路
//①返回值长度累加==接口数据总长度。适用于复杂的字节,同时包含数字,汉字,图片等
//②写一个循环 do while , 根据返回值长度是否为0来判断,适用于简单的字节
对于第二种中情况,一边接收一边解析,然后累加解析结果,如果是第一种情况,就不能这样处理,必须保证 byte[] 的对应的数据(图片)是完整数据后,才可解析,当前如果是这种复杂的处理,前提是各部分对应的长度是已知,根据这些长度截取对应的索引部分,对号入座去执行解析,这样才更稳妥。
byte[] 解析、转码二三事的更多相关文章
- Jetty源码学习-编译Jetty源码二三事
工作小几个月了,JDK基础和web应用框架学的的差不多了,开始学习Jetty源码,费了小半天才编译成功,把自己拆过的坑记录下来. 编译前的环境: MAVEN 3.3.Eclips eLuna Serv ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- asp.net 生成、解析条形码和二维码
原文 asp.net 生成.解析条形码和二维码 一.条形码 一维码,俗称条形码,广泛的用于电子工业等行业.比如我们常见的书籍背面就会有条形码,通过扫描枪等设备扫描就可以获得书籍的ISBN(Intern ...
- Unity UGUI图文混排源码(二)
Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...
- Flink 源码解析 —— 源码编译运行
更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...
- 【C#夯实】我与接口二三事:IEnumerable、IQueryable 与 LINQ
序 学生时期,有过小组作业,当时分工一人做那么两三个页面,然而在前端差不多的时候,我和另一个同学发生了争执.当时用的是简单的三层架构(DLL.BLL.UI),我个人觉得各写各的吧,到时候合并,而他觉得 ...
- EventBus源码解析 源码阅读记录
EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...
- 数据结构图文解析之:二叉堆详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- node.js Websocket实现扫码二维码登录---GoEasy
最近在做一个扫码登录功能,为此我还在网上搜了一下关于微信的扫描登录的实现方式.当这个功能完成了后,我决定将整个实现思路整理出来,方便自己以后查看也方便其他有类似需求的程序猿些. 要实现扫码登录我们需要 ...
随机推荐
- Java 判断字符串 中文是否为乱码
import java.util.regex.Matcher; import java.util.regex.Pattern; public class ChineseUtill { private ...
- 手机配置代理报错invalid host header
手机配置代理后浏手机弹出页面报错invalid host header,因为我是用fiddler配置的,所以这时候就要看下自己配置完之后,是否重启,重启之后就没问题了. fiddle配置参考:http ...
- 深度学习中交叉熵和KL散度和最大似然估计之间的关系
机器学习的面试题中经常会被问到交叉熵(cross entropy)和最大似然估计(MLE)或者KL散度有什么关系,查了一些资料发现优化这3个东西其实是等价的. 熵和交叉熵 提到交叉熵就需要了解下信息论 ...
- 关于“.bash_profile”和“.bashrc”区别的总结
bash的startup文件 Linux shell是用户与Linux系统进行交互的媒介,而bash作为目前Linux系统中最常用的shell,它支持的startup文件也并不单一,甚至容易让人感到费 ...
- 死锁的原因及解决办法RLock递归锁
死锁 说到死锁,可以讲一个科学家吃面的问题: 有几个科学家在一张桌子旁,桌子上只有一把筷子和一碗面,我们将面和筷子都加锁.这是可能会导致一个科学家抢到面,另一个科学家抢到筷子,这是就全部阻塞了,这就是 ...
- R 544
F2: 什么dfs根本不会啊,只会瞎贪心... 我们考虑先连哪些边,对于u,v两个点,如果u,v所在的联通块都与1相连的话,那我们肯定先不连这种边吧. 因为太亏了啊... 总而言之我们要在不影响答案的 ...
- Java课程课堂测试05
大致要求:将十道计算题输出至TXT文件,再读取文件至控制台,然后在控制台中输入答案并评判对错 我在大致的要求当中已经将我的设计思路体现了出来 首先,实现计算题的设计,第二步要对计算题循环,将答案存到一 ...
- LeetCode 19 - 删除链表的倒数第N个节点 - [链表]
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ 题解: 两个 $p,q$ 指针均指向头,然后 $q$ 先 ...
- InnoDB中锁的模式
Ⅰ.总览 S行级共享锁 lock in share mode X行级排它锁 增删改 IS意向共享锁 IX意向排他锁 AI自增锁 Ⅱ.锁之间的兼容性 兼 X IX S IS X × × × × IX × ...
- ExceptionLess使用
1.os使用windows server 2012,省的升级iis express-iis 8(测试环境是IIS Express 8,生产环境IIS 7.5).PowerShell 3+了. 2.wi ...