首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用php对文件进行二进制安全写入,以创建DBF文件

使用php对文件进行二进制安全写入,以创建DBF文件
EN

Stack Overflow用户
提问于 2018-06-01 00:24:07
回答 1查看 655关注 0票数 1

我需要使用php函数拆分一个大的DBF文件,这意味着我有1000条记录,我必须创建2个文件,每个文件有500条记录。

我没有任何可用的dbase扩展,我也不能安装它,所以我必须使用基本的php函数。使用基本的fread函数,我能够正确地读取和解析文件,但是当我尝试编写新的dbf时,我遇到了一些问题。

据我所知,DBF文件的结构是两行文件:第一行包含文件信息,头信息,它是二进制的。第二行包含数据,它是纯文本。所以我想简单地写一个新的二进制文件,复制第一行,并手动添加第一个文件中的第一个记录,另一个文件中的其他记录。

这是我用来解析文件的代码,它工作得很好

代码语言:javascript
复制
    $fdbf = fopen($_FILES['userfile']['tmp_name'],'r');
    $fields = array();
    $buf = fread($fdbf,32);
    $header=unpack( "VRecordCount/vFirstRecord/vRecordLength", substr($buf,4,8));
    $goon = true;
    $unpackString='';
    while ($goon && !feof($fdbf)) { // read fields:
        $buf = fread($fdbf,32);
        if (substr($buf,0,1)==chr(13)) {$goon=false;} // end of field list
        else {
            $field=unpack( "a11fieldname/A1fieldtype/Voffset/Cfieldlen/Cfielddec", substr($buf,0,18));
            
            $unpackString.="A$field[fieldlen]$field[fieldname]/";
            array_push($fields, $field);
        }
    }
    fseek($fdbf, 0);
    $first_line = fread($fdbf, $header['FirstRecord']+1);
    
    fseek($fdbf, $header['FirstRecord']+1); // move back to the start of the first record (after the field definitions)

first_line是包含头数据的变量,但当我尝试将其写入新文件时,发生了一些错误,行的写入与读取时不完全相同。这是我用来写的代码:

代码语言:javascript
复制
$handle_log = fopen($new_filename, "wb");
fwrite($handle_log, $first_line, strlen($first_line) );
fwrite($handle_log, $string );
fclose($handle_log);

我尝试按照建议将DBF值添加到fopen mode参数中,以便以二进制方式打开它,我还建议准确添加字符串的长度,以避免某些字符的条纹,但失败了,因为所有写入的文件都不是正确的DBF格式。我能做些什么来实现我的目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-17 06:38:14

据我所知,DBF文件的结构是两行文件:第一行包含文件信息,头信息,它是二进制的。第二行包含数据,它是纯文本。

嗯,事情要比这复杂一点。

有关dbf文件格式的完整说明,请参阅here

因此,如果您可以使用库来读写dbf文件,这将是最好的。

如果你真的需要自己做这件事,下面是最重要的部分:

  • Dbf是一种二进制文件格式,因此您必须以二进制的形式对其进行读写。例如,记录的数量存储在32位整数中,该整数可以包含零字节。你不能在那个二进制数据上使用字符串函数。例如,strlen()将扫描数据直到第一个空字节,它出现在那个32位整数中,并返回错误的值。
  • 如果你拆分文件(记录),你将不得不调整标题中的记录计数。
  • 当拆分记录时,请记住每条记录的前面都有一个额外的字节,如果记录没有被删除,就会有一个空格0x20,如果记录被删除了,就会有一个星号0x2A。(例如,如果您有4个10字节的字段,则每个记录的长度将为41) -标头中也提供了该值:bytes 10-11 - 16-bit number - Number of bytes in the record. (Least significant byte first)
  • The文件可能以文件结束标记0x1A结尾,因此您也必须进行检查。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50628785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档