尽管php是用C语言开发的,不过令我不解的是php没有提供对结构体struct的直接支持。

不过php提供了pack和unpack函数,用来进行二进制数据(binary data)和php内部数据的互转:

stringpack(string$format[,mixed$args[,mixed$...]])

//Pack given arguments into binary string according to format.

arrayunpack(string$format,string$data)

//Unpacks from a binary string into an array according to the given format.

其中,$format跟perl里的pack格式类似,有如下一些(中文是我加的,有不准确的欢迎提出):

a NUL-padded string,即“\0”作为“空字符”的表示形式

A SPACE-padded string,空格作为“空字符”的表示形式

h Hex string, low nibble first,升序位顺序

H Hex string, high nibble first,降序位顺序

c signed char,有符号单字节

C unsigned char,无符号单字节

s signed short (always 16 bit, machine byte order)

S unsigned short (always 16 bit, machine byte order)

n unsigned short (always 16 bit, big endian byte order)

v unsigned short (always 16 bit, little endian byte order)

i signed integer (machine dependent size and byte order)

I unsigned integer (machine dependent size and byte order)

l signed long (always 32 bit, machine byte order)

L unsigned long (always 32 bit, machine byte order)

N unsigned long (always 32 bit, big endian byte order)

V unsigned long (always 32 bit, little endian byte order)

f float (machine dependent size and representation)

d double (machine dependent size and representation)

x NUL byte,实际使用的时候作为跳过多少字节用,很有用

X Back up one byte,后退1字节

@ NUL-fill to absolute position,实际使用的时候作为从开头跳到某字节用,很有用

实际使用发现:C里的“\0”(即字符串终止符)在php里并不是终止符,而是作为了字符串的一部分。因此,必须对“\0”进行特殊处理,才能进行struct和php内部数据的完美互转。比如 char name[10]; 如果实际数据是“62 69 61 6E 00 62 69 61 6E 00”,在C语言里第5个位置有终止符,name应该是“bian”;而用了unpack转换以后在php里的name却是“bian\0bian\0”。

一开始我用了strpos函数找到“\0”的位置,然后进行substr截取:

$name=substr($name,0,strpos($name,"\0"));

不过很Faint的事情发生了,不知道是strpos的bug还是substr的bug(其实测试一下就知道,懒得试),有些字符串没问题,有些字符串却只能得到空值(即$name == ”)。很是郁闷,后来找了个strtok函数,这下没有问题了:

$name=strtok($name,"\0");

难为大家看了那么多,下面写个完整的php读取二进制数据流(C语言结构体struct数据)文件的示例代码:

首先是C的struct定义示例,为了演示,我就写个简单点的,实际对照上面那个$format格式表应该没有问题:

structBIANBIAN{

charname[10];

charpass[33];

intage;

unsignedcharflag;

};

比如有个“bianbian.org”文件,内容就是上面的N个BIANBIAN结构体构成的。读取的php代码:

//下面根据struct确定$format,注意int类型跟机器环境有关,我的32位Linux是4个长度

$format='a10name/a33pass/iage/Cflag';

//确定一个struct占用多少长度字节,如果只是读取单个结构体这是不需要的

$length=10+33+4+1;

//也可以用fopen + fread + fclose,不过file_get_contents因为可以mmap,效率更高

$data=file_get_contents('bianbian.org','r');

for($i=0,$c=strlen($data);$i

$bianbian=unpack("@$i/$format",$data);

//reference传递是php 5才支持的,如果用php4,得用其他办法

foreach($bianbianas&$value){

if(is_string($value)){

$value=strtok($value,"\0");

}

}

print_r($bianbian);

}

//输出为array,即类似:

Array

(

[name]=>'bianbian'

[pass]=>'bianbian.org'

[age]=>100

[flag]=>0

)

...

pack应该跟unpack相反。

php cunstruct,php读取二进制流(C语言结构体struct数据文件)相关推荐

  1. C语言 结构体Struct 中冒号的用法

    C语言 结构体Struct 中冒号的用法 本文有部分内容参考菜鸟教程-C 位域 . 关于"位域"的说明 有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位. ...

  2. c语言结构体定义蚂蚁,C语言结构体(struct)常见使用方法

    C语言结构体(struct)常见使用方法 C语言结构体(struct)常见使用方法 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合) ...

  3. C语言 结构体 struct Cat cat1;

    引入 使用传统技术解决 需要定义多个变量或数组 结构体与结构体变量的关系示意图 类似Java类中的对象(结构体)与属性(结构体变量) 一切物体都可以看作对象(结构体) 补充:C语言数据类型 简单使用案 ...

  4. C语言结构体struct详解与实例

    目录 1.定义 2.应用 2.1初始化 2.2使用 3.结构体对齐规则与存储 1.定义 C语言中结构体(struct关键字定义)是一种自定义数据类型.通过结构体的定义可以将多种不同类型数据形成一个组合 ...

  5. 关于C语言结构体(struct)介绍

    转自:微点阅读  https://www.weidianyuedu.com 导读:       C语言结构体,怎么理解? 你可以把它想象成一个桌面上的文件夹,这个文件夹里面可以有各种各样的文件,当然也 ...

  6. C语言 结构体struct总结

    文章目录 一.前言 二.结构体的引入 三.结构体声明 四.结构体变量的定义 五.结构体变量的初始化 六.结构体变量成员的访问 七.结构体存储原理 八.结构体数组 8.1结构体数组的定义 8.2结构体数 ...

  7. C语言——结构体struct与typedef的使用

    我们常常在某些C语言代码中看到有时候typedef关键字和struct一起连用定义结构体,有时候只用struct关键字直接定义结构体,在此记录两者的一些用法,给自己做一个笔记,希望对大家也有所帮助.如 ...

  8. c语言结构体数组存入文件_关于从文件中读取数据并写入结构体数组

    已结贴√ 问题点数:25 回复次数:10 关于从文件中读取数据并写入结构体数组 各位大大好,本人新手一枚,最近写简单的通讯录的c程序,其他功能完好,最后一个将txt文件中的数据写入结构体数组的函数无法 ...

  9. c语言结构体语法分析,C语言结构体struct的语法解析

    本节内容需要结合视频讲解才能更容易理解,视频播放地址如下: 用java开发编译器 本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如 ...

  10. C语言结构体struct的语法解析

    本节内容需要结合视频讲解才能更容易理解,视频播放地址如下: 用java开发编译器 本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如 ...

最新文章

  1. python 字典、列表、字符串 之间的转换
  2. 关于Java为什么配置好环境变量但是不能在命令行cmd运行javac的问题
  3. 单模光电转换器怎么接_我对汽车电子电磁兼容测试实验室使用的光电收发器之使用管理方式的一些看法...
  4. Anaconda创建虚拟环境报错—UnavailableInvalidChannel: The channel is not accessible or is invalid
  5. TurboMail 邮件系统V5.2.0新品发布会盛况直击
  6. 2021-09-1031. 下一个排列 数组
  7. ODBC驱动程序丢失解决方法
  8. 联想m7216更换墨粉流程图_联想M7216打印机加墨粉后还显示墨粉用完是为什么?...
  9. 关于1KB病毒的清除
  10. 管道—过滤器简介 软件体系结构
  11. hdu 3987 - 最小割最少割边
  12. 运动世界校园【夜神模拟器】5.30
  13. Hdmi 和vga 接口有什么区别?
  14. 常见算法整理---50题
  15. axios在ie浏览器下提示promise未定义
  16. 计算机网络(四)——组建对等网
  17. Linux基础命令----tail 查看文件尾部内容
  18. linux vi 删除行命令,在Vim/Vi中删除行、多行、行范围、所有行及包含模式的行
  19. 微信浏览器页面样式不生效
  20. 编译基于obs-studio的阿里巴巴直播工具tblive的过程和常见问题解决

热门文章

  1. 数据库 Oracle监听实例详解
  2. ubuntu启动时的初始化信息二
  3. PACKAGE-INFO.JAVA 作用及用法详解
  4. 【算法】排序_堆排序
  5. 【Android综合应用】概述
  6. Unity自定义Editor简明教程
  7. java 天上掉东西游戏的源代码_【小游戏】前两天的小游戏终于调试成功了。。。。直接源代码...
  8. 有生成的日志的监控电脑性能的软件吗_全链路监控:方案概述与对比,看完你就懂...
  9. postgresql 数据库连接数查询
  10. Oracle 查看表空间使用率,表空间扩展