如何在 Matlab 中打开 DBase 文件(.DBF)?

2023-11-25

我已经在 Matlab Central 中进行了谷歌搜索,但找不到任何直接在 Matlab 中打开 DBF 文件的方法。 TMW File Exchange 中有一些对 DBFREAD 函数的引用,但它不再可用。真的有问题吗?

我确实有数据库工具箱,但在那里找不到 dbf 支持。

我不想使用 Excel 或其他工具在 Matlab 之外转换文件,因为我有很多文件需要处理。 ODBC 也不好,我还需要代码在 Mac 和 Unix 下工作。

请帮忙。


我联系了 DBFREAD 函数的作者 Brian Madsen,该函数已从 File Exchange 中删除,可能是因为 Mathworks 将在未来的某个版本中将此函数包含到 MATLAB 中。 Brian 好心允许我在这里发布这个函数。所有版权信息均保持不变。我只修改了第 33-38 行以允许 DBFREAD 读取工作目录之外的文件。

function [dbfData, dbfFieldNames] = dbfread(filename, records2read, requestedFieldNames)
%DBFREAD Read the specified records and fields from a DBF file.
%
%   [DATA, NAMES] = DBFREAD(FILE) reads numeric, float, character and date
%   data and field names from a DBF file, FILE.
%
%   [DATA, NAMES] = DBFREAD(FILE, RECORDS2READ) reads only the record
%   numbers specified in RECORDS2READ, a scalar or vector.
%
%   [DATA, NAMES] = DBFREAD(FILE, RECORDS2READ, REQUESTEDFIELDNAMES) reads
%   the data from the fields, REQUESTEDFIELDNAMES, for the specified
%   records. REQUESTEDFIELDNAMES must be a cell array. The fields in the
%   output will follow the order given in REQUESTEDFIELDNAMES.
%
%   Examples:
%
%       % Get all records and a list of the field names from a DBF file.
%       [DATA,NAMES] = dbfread('c:\matlab\work\mydbf')
%
%       % Get data from records 3:5 and 10 from a DBF file.
%       DATA = dbfread('c:\matlab\work\mydbf',[3:5,10])
%
%       % Get data from records 1:10 for three of the fields in a DBF file.
%       DATA = dbfread('c:\matlab\work\mydbf',1:10,{'FIELD1' 'FIELD3' 'FIELD5'})
%
%   See also XLSREAD, DLMREAD, DLMWRITE, LOAD, FILEFORMATS, TEXTSCAN.

% Copyright 2008 The MathWorks, Inc.
% $Revision: 1.0 $   $Date: 2008/04/18 05:58:17 $

[pathstr,name,ext] = fileparts(filename);

dbfFileId = fopen(filename,'r','ieee-le');
if (dbfFileId == -1)
    dbfFileId = fopen(fullfile(pathstr, [name '.dbf']),'r','ieee-le');
end
if (dbfFileId == -1)
    dbfFileId = fopen(fullfile(pathstr, [name '.DBF']),'r','ieee-le');
end

if (dbfFileId == -1)
    eid = sprintf('MATLAB:%s:missingDBF', mfilename);
    msg = sprintf('Failed to open file %s.dbf or file %s.DBF.',...
            name, name);
    error(eid,'%s',msg)
end

info = dbfinfo(dbfFileId);
if ~exist('requestedFieldNames','var')
    dbfFieldNames = {info.FieldInfo.Name};
    requestedFieldNames = dbfFieldNames;
else
    dbfFieldNames = (info.FieldInfo(matchFieldNames(info,requestedFieldNames)).Name);
end
fields2read = matchFieldNames(info,requestedFieldNames);

% The first byte in each record is a deletion indicator
lengthOfDeletionIndicator = 1;

if ~exist('records2read','var')
    records2read = (1:info.NumRecords);
elseif max(records2read) > info.NumRecords
    eid = sprintf('MATLAB:%s:invalidRecordNumber', mfilename);
    msg = sprintf('Record number %d does not exist, please select from the range 1:%d.',...
        max(records2read), info.NumRecords);
    error(eid,'%s',msg)
end

% Loop over the requested fields, reading in the data
dbfData = cell(numel(records2read),numel(fields2read));
for k = 1:numel(fields2read),
    n = fields2read(k);
    fieldOffset = info.HeaderLength ...
                  + sum([info.FieldInfo(1:(n-1)).Length]) ...
                  + lengthOfDeletionIndicator;
    fseek(dbfFileId,fieldOffset,'bof');
    formatString = sprintf('%d*uint8=>char',info.FieldInfo(n).Length);
    skip = info.RecordLength - info.FieldInfo(n).Length;
    data = fread(dbfFileId,[info.FieldInfo(n).Length info.NumRecords],formatString,skip);
    dbfData(:,k) = feval(info.FieldInfo(n).ConvFunc,(data(:,records2read)'));
%     dbfData(:,k) = info.FieldInfo(n).ConvFunc(data(:,records2read)');
end

fclose(dbfFileId);

%--------------------------------------------------------------------------
function fields2read = matchFieldNames(info, requestedFieldNames)
% Determine which fields to read.

allFieldNames = {info.FieldInfo.Name};
if isempty(requestedFieldNames)
    if ~iscell(requestedFieldNames)
        % Default case: User omitted the parameter, return all fields.
        fields2read = 1:info.NumFields;
    else
        % User supplied '{}', skip all fields.
        fields2read = [];
    end
else
    % Match up field names to see which to return.
    fields2read = [];
    for k = 1:numel(requestedFieldNames)
        index = strmatch(requestedFieldNames{k},allFieldNames,'exact');
        if isempty(index)
            wid = sprintf('MATLAB:%s:nonexistentDBFName',mfilename);
            wrn = sprintf('DBF name ''%s'' %s\n%s',requestedFieldNames{k},...
                     'doesn''t match an existing DBF name.',...
                     '         It will be ignored.');
            warning(wid,wrn)
        end
        for l = 1:numel(index)
            % Take them all in case of duplicate names.
            fields2read(end+1) = index(l);
        end
    end
end

%--------------------------------------------------------------------------

function info = dbfinfo(fid)
%DBFINFO Read header information from DBF file.
%   FID File identifier for an open DBF file.
%   INFO is a structure with the following fields:
%      Filename       Char array containing the name of the file that was read
%      DBFVersion     Number specifying the file format version
%      FileModDate    A string containing the modification date of the file
%      NumRecords     A number specifying the number of records in the table
%      NumFields      A number specifying the number of fields in the table
%      FieldInfo      A 1-by-numFields structure array with fields:
%         Name        A string containing the field name 
%         Type        A string containing the field type 
%         ConvFunc    A function handle to convert from DBF to MATLAB type
%         Length      A number of bytes in the field
%      HeaderLength   A number specifying length of the file header in bytes
%      RecordLength   A number specifying length of each record in bytes

%   Copyright 1996-2005 The MathWorks, Inc.
%   $Revision: 1.1.10.4 $  $Date: 2005/11/15 01:07:13 $

[version, date, numRecords, headerLength, recordLength] = readFileInfo(fid);
fieldInfo = getFieldInfo(fid);

info.Filename     = fopen(fid);
info.DBFVersion   = version;
info.FileModDate  = date;
info.NumRecords   = numRecords;
info.NumFields    = length(fieldInfo);
info.FieldInfo    = fieldInfo;
info.HeaderLength = headerLength;
info.RecordLength = recordLength;

%----------------------------------------------------------------------------
function [version, date, numRecords, headerLength, recordLength] = readFileInfo(fid)
% Read from File Header.

fseek(fid,0,'bof');

version = fread(fid,1,'uint8');

year  = fread(fid,1,'uint8') + 1900;
month = fread(fid,1,'uint8');
day   = fread(fid,1,'uint8');

dateVector = datevec(sprintf('%d/%d/%d',month,day,year));
dateForm = 1;% dd-mmm-yyyy
date = datestr(dateVector,dateForm);

numRecords   = fread(fid,1,'uint32');
headerLength = fread(fid,1,'uint16');
recordLength = fread(fid,1,'uint16');

%----------------------------------------------------------------------------
function fieldInfo = getFieldInfo(fid)
% Form FieldInfo by reading Field Descriptor Array.
%
% FieldInfo is a 1-by-numFields structure array with the following fields:
%       Name      A string containing the field name 
%       Type      A string containing the field type 
%       ConvFunc  A function handle to convert from DBF to MATLAB type
%       Length    A number equal to the length of the field in bytes

lengthOfLeadingBlock    = 32;
lengthOfDescriptorBlock = 32;
lengthOfTerminator      =  1;
fieldNameOffset         = 16;  % Within table field descriptor
fieldNameLength         = 11;

% Get number of fields.
fseek(fid,8,'bof');
headerLength = fread(fid,1,'uint16');
numFields = (headerLength - lengthOfLeadingBlock - lengthOfTerminator)...
               / lengthOfDescriptorBlock;

% Read field lengths.
fseek(fid,lengthOfLeadingBlock + fieldNameOffset,'bof');
lengths = fread(fid,[1 numFields],'uint8',lengthOfDescriptorBlock - 1);

% Read the field names.
fseek(fid,lengthOfLeadingBlock,'bof');
data = fread(fid,[fieldNameLength numFields],...
             sprintf('%d*uint8=>char',fieldNameLength),...
             lengthOfDescriptorBlock - fieldNameLength);
data(data == 0) = ' '; % Replace nulls with blanks
names = cellstr(data')';

% Read field types.
fseek(fid,lengthOfLeadingBlock + fieldNameLength,'bof');
dbftypes = fread(fid,[numFields 1],'uint8=>char',lengthOfDescriptorBlock - 1);

% Convert DBF field types to MATLAB types.
typeConv = dbftype2matlab(upper(dbftypes));

% Return a struct array.
fieldInfo = cell2struct(...
    [names;  {typeConv.MATLABType}; {typeConv.ConvFunc}; num2cell(lengths)],...
    {'Name', 'Type',                'ConvFunc',          'Length'},1)';

%----------------------------------------------------------------------------
function typeConv = dbftype2matlab(dbftypes)
% Construct struct array with MATLAB types & conversion function handles.

typeLUT = ...
    {'N', 'double', @str2double2cell;...   % DBF numeric
     'F', 'double', @str2double2cell;...   % DBF float
     'C', 'char',   @cellstr;...           % DBF character
     'D', 'char',   @cellstr};             % DBF date

unsupported = struct('MATLABType', 'unsupported', ...
                     'ConvFunc',   @cellstr);

% Unsupported types: Logical,Memo,N/ANameVariable,Binary,General,Picture

numFields = length(dbftypes);
if numFields ~= 0
  typeConv(numFields) = struct('MATLABType',[],'ConvFunc',[]);
end
for k = 1:numFields
    idx = strmatch(dbftypes(k),typeLUT(:,1));
    if ~isempty(idx)
        typeConv(k).MATLABType = typeLUT{idx,2};
        typeConv(k).ConvFunc   = typeLUT{idx,3};
    else
        typeConv(k) = unsupported;
    end
end

%----------------------------------------------------------------------------
function out = str2double2cell(in)
% Translate IN, an M-by-N array of class char, to an M-by-1 column vector
% OUT, of class double.  IN may be blank- or null-padded. If IN(k,:) does
% not represent a valid scalar value, then OUT(k) has value NaN.
if isempty(in)
    out = {[NaN]};
    return
end

% Use sprintf when possible, but fall back to str2double for unusual cases.
fmt = sprintf('%%%df',size(in,2));
[data count] = sscanf(reshape(in',[1 numel(in)]),fmt);
if count == size(in,1)
    out = cell(count,1);
    for k = 1:count
        out{k} = data(k);
    end
else
    out = num2cell(str2double(cellstr(in)));
end

UPDATE

如果输入参数中的位数不同,STR2DOUBLE 2CELL 子功能有时会无法正常工作(请参阅这次讨论).

这是我的 STR2DOUBLE2CELL 版本:

function out = str2double2cell(in)
% Translate IN, an M-by-N array of class char, to an M-by-1 column vector
% OUT, of class double.  IN may be blank- or null-padded. If IN(k,:) does
% not represent a valid scalar value, then OUT(k) has value NaN.
if isempty(in)
    out = {[NaN]};
    return
end

out = cellfun(@str2double,cellstr(in),'UniformOutput',false);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Matlab 中打开 DBase 文件(.DBF)? 的相关文章

  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk
  • 绘制布朗运动 matlab

    首先 我只想说我不太习惯使用matlab 但我需要一个作业 我应该创建一个 布朗运动 我的代码目前如下所示 clf hold on prompt Ge ett input size input prompt numParticles inp
  • 在 Python 上显示 Matlab mat 文件中的图像

    我目前正在尝试显示从此下载的 Mat 文件中的图像site http www rctn org bruno sparsenet 这是一个 mat 文件 所以我尝试使用 scipy io loadmat 函数加载它 但我似乎无法绘制图像 我究
  • 基本矩阵错误?

    我试图通过扫描从相机拍摄的两个图像 检测图像中的特征 匹配它们 创建基本矩阵 使用相机内在函数计算基本矩阵 然后分解它以找到旋转和翻译 这是matlab代码 I1 rgb2gray imread 1 png I2 rgb2gray imre
  • Matlab下降低图像质量

    问候 我正在尝试找到一种简单的方法来处理图像 以便将其质量从 8 位降低到 3 位 实现这一目标的最简单方法是什么 干杯 如果要线性缩放 只需将每个像素值除以 255 7 即 如果原始图像存储在矩阵 I 中 则让低分辨率图像 J I 255
  • 在Matlab图例中使用Latex?

    我的 matlab 不接受我的 Latex 例如 如果我使用legend b 6 rightarrow b 7 它没有向我显示箭头 我该如何解决这个问题 尝试使用 Latex 解释器 例如 legend b 6 rightarrow b 7
  • MATLAB 子图标题和轴标签

    我有以下脚本来最终绘制 4 x 2 子图 files getAllFiles preliminaries n size files cases cell 1 n m cell 1 n for i 1 1 n S load files i c
  • 将值从 C++ MEX 文件返回到 MATLAB

    我正在编写一个从 C 代码中检索数据的 MATLAB 程序 为此 我在 MATLAB 中创建了一个 MEX 文件和一个网关 mexFunction 虽然可以在 MATLAB 中读取读取值 但我无法检索它来使用它 如果不清楚 我有与这里完全相
  • GO TO 语句 - Fortran 到 Matlab

    我一直在努力将此网格搜索代码从 Fortran 转换为 Matlab 但是我无法正确合并 GO TO 语句 我正在尝试使用 while 循环 但我认为我需要其他东西来结束搜索 任何帮助将不胜感激 vmax 1 0E 15 amax G 1
  • 使用 scipy.io 将 python pandas dataframe 转换为 matlab 结构

    我正在尝试使用 scipy io 将 pandas 数据帧保存到 matlab mat 文件 我有以下内容 array1 np array 1 2 3 array2 np array a b c array3 np array 1 01 2
  • MATLAB 问题中的 Parfor

    为什么我不能使用parfor在这段代码中 parfor i 1 r for j 1 N r xr j N r i 1 x i r j 1 end end 这是错误 错误 parfor 中的变量 xr 无法分类 请参阅 MATLAB 中的并行
  • 在 numpy/scipy 中查找 matlab 函数

    是否有一个等价的函数find A gt 9 1 来自 numpy scipy 的 matlab 我知道有nonzeronumpy 中的函数 但我需要的是第一个索引 以便我可以在另一个提取的列中使用第一个索引 Ex A 1 2 3 9 6 4
  • Matlab 错误:()-索引必须出现在索引表达式的最后

    我有这段代码 想要在制表符分隔的 txt 文件中写入一个数组 fid fopen oo txt wt for x 1 length s fprintf fid s t n s x 1 end fclose fid 但我收到此错误 Error
  • 如何使用 MATLAB 的“等值面”函数创建三角球体

    如何创建一个三角球体 其中每个三角形的面面积相同 我想要这样的东西 http imageshack us a img198 5041 71183923 png http imageshack us a img198 5041 7118392
  • 一次分配多个字段的聪明方法?

    由于遗留函数调用 我有时被迫编写像这样的丑陋的包装器 function return someWrapper someField a someField a b someField b and so on realistically it
  • 继续在 Matlab 中一遍又一遍地播放声音?

    我正在尝试创建一个 MATLAB 程序来每隔几分钟一遍又一遍地播放声音 现在我将其设置为每隔几秒播放一次 只是为了消除系统中的一些错误 但是 当我的程序尝试重播声音时 我收到此错误 Error using gt audioplayer au
  • 如何将条形图的 XtickLabels 向左移动?

    我目前正在尝试创建频率直方图 为此 我必须创建一个条形图 条形图之间没有空格 然而 这集中于XTickLabels在酒吧的中间 由于它是一个直方图 我希望数值位于每个条形之间的线上 以便它可以直观地指示间隔 本质上 我需要将所有刻度标签移至
  • 在 Matlab 中保存当前运行的脚本

    有没有办法保存Matlab中当前运行的脚本 我有一个脚本 它会自动备份一组脚本 但如果我更改了当前脚本 则保存的版本将过期 也许可以调用一些java Thanks 在 Yair Altman 网站上的某个地方 请参阅我的其他答案中的链接 他
  • 对多个属性使用一种设置方法 MATLAB

    我有几个属性基本上使用相同的属性set method classdef MyClass properties A B end methods function mc MyClass a b Constructor mc A a mc B b
  • 如何在Matlab中自定义轮廓线?

    我正在准备一个等高线图 我应该在其中突出显示特定级别的等高线 例如 我的轮廓线值位于 1 和 1 之间 我想突出显示与值 0 相对应的线 我尝试使用以下过程来执行此操作 M c contourf longitude latitude del

随机推荐

  • AX、AH、AL如何映射到EAX?

    我对x86寄存器的理解是 每个寄存器都可以被整个32位代码访问 并且它被分成多个可访问的寄存器 在这个例子中EAX作为一个 32 位寄存器 如果我们调用AX它应该返回前 16 位 如果我们调用AH or AL它应该返回 16 位之后的接下来
  • haskell中具有多参数函数的点运算符

    我想在 haskell 中编写一个无点函数 为了简单起见 我想创建这个函数 maxmin Ord a gt a gt a gt a gt a maxmin a b c max a min b c 我可以将其改进为 maxmin a b ma
  • ImageIO: JPEG 损坏的 JPEG 数据:数据段过早结束 iphone - 如何捕获此问题?

    我通过 HTTP 下载图像时收到此错误 我看过在这里回答但即使有效的图像也不会返回YES从函数 还有其他想法吗 获取图像的代码很简单 这发生在后台线程中 NSData data NSData dataWithContentsOfURL NS
  • 导航控制器透明栏样式不起作用

    我正在使用导航控制器 并且我将样式设置为 navController navigationBar barStyle UIBarStyleBlackTranslucent 但是当我运行我的程序时 导航控制器看起来像是在白色背景之上 而不是我的
  • 将总行附加到数据帧后删除 pandas 数据帧索引的名称

    我按一周中的每一天计算了一系列总计提示 并将其附加到底部totalspt数据框 我已经设置了index name为了totalspt数据框为无 然而 当数据框显示默认的 0 1 2 3 索引时 它不会在索引正上方的左上角显示默认的空单元格
  • 获取类型错误:__init__() 缺少 1 个必需的位置参数:尝试在包含条目的子表之后添加父表时“on_delete”

    我的 sqlite 数据库中有两个类 一个名为的父表Categorie子表称为Article 我首先创建了子表类并添加了条目 所以首先我有这个 class Article models Model titre models CharFiel
  • 我创建了一个带有自动刷新功能的 PrintWriter;为什么不自动冲洗?

    我的客户端是一个网络浏览器 并使用以下网址向我的服务器发送请求 http localhost 这是服务器端代码 问题出在run方法上ServingThread class class ServingThread implements Run
  • 学说2中的多态关系

    有没有办法实现Laravel在主义上的多态关系 这是一个例子 class Address protected street public function setStreet public function getStreet class
  • 枚举的枚举为 NULL

    我正在为我的 Java 1 6 大学课程开发一个 LALG 编译器 所以我上了类型课和语法课 枚举类型 public enum EnumTypes A OLA B MUNDO C HELLO D WORLD The order below
  • spring security中的手动认证逻辑应该去哪里——服务层还是表示层?

    我有这段代码 UserDetails userDetails userDetailsServiceImpl loadUserByUsername email Authentication authentication new Usernam
  • 从 Android 检索 GPS 修复中使用的卫星数量

    我正在尝试检索 GPS 修复中使用的卫星数量 我实现了两种不同的方法 如下所示 package ti utils import android app Activity import android content Context impo
  • 我可以复制或拦截 Java 中的输出流吗?

    我想拦截标准输出流 然后将内容复制到另一个流 但我也希望保持标准输出流像原来一样 我可以用 Java 实现这一点吗 您可以使用类似示例的内容TeeOutputStream在这里解释编写您自己的 Java I O 流类 基本上 您创建一个 T
  • 目前在 Jupyter/iPython 中动态更新绘图的正确方法是什么?

    在答案中如何在 ipython 笔记本中动态更新循环中的绘图 在一个单元格内 给出了如何在 Python 循环中动态更新 Jupyter Notebook 内的绘图的示例 然而 这是通过在每次迭代中销毁并重新创建绘图来实现的 并且其中一个线
  • 将缺失的日期添加到 pandas 数据框中

    我的数据可以在给定日期有多个事件 也可以在某个日期没有事件 我记录这些事件 按日期计数并绘制它们 然而 当我绘制它们时 我的两个系列并不总是匹配 idx pd date range df simpleDate min df simpleDa
  • 是否存在占用 0 字节的 C++ 类型

    我试图声明一个占用零字节的 C 变量 它在一个联合体中 我从 int 0 类型开始 我不知道这是否实际上是零字节 尽管 sizeof int 0 是 0 我需要一种更好的方法来声明 0 字节类型 并且希望可以将其类型定义为 nullType
  • 无法使用 127.0.0.1 连接到 mysql

    使用以下代码我可以连接到mysql mysql connect localhost username 但如果我改变localhost to 127 0 0 1我收到以下错误 无法连接到 127 0 0 1 上的 MySQL 服务器 13 为
  • 命令行参数的Shell脚本密码安全

    如果我使用密码作为命令行参数 则它在系统上是公开的ps 但是如果我在 bash shell 脚本中并且执行如下操作 somecommand p mypassword 这仍然会出现在进程列表中吗 或者这样安全吗 子流程怎么样 不安全吧 协进程
  • 图库/AdapterView 子可绘制状态

    我正在使用图库视图 其中与每个项目相对应的视图都非常重要 并且由文本和多个按钮组成 当我单击以拖动图库视图 不在按钮之一上的某处 时 按钮的可绘制状态更改为按下 并且看起来好像所有按钮当前都被按下 此外 选定状态也会发生相同的行为 例如 子
  • 轻量级8字节哈希函数算法

    我需要从可变长度字符串中提取 8 字节摘要 因此我正在寻找将在 c c 中实现的算法 这将是微控制器上数字签名过程的一部分 因此它必须是 可以用几行代码编写 因为必须保留尽可能少的固件 资源消耗低 特别是RAM 最好小于100字节 足够强大
  • 如何在 Matlab 中打开 DBase 文件(.DBF)?

    我已经在 Matlab Central 中进行了谷歌搜索 但找不到任何直接在 Matlab 中打开 DBF 文件的方法 TMW File Exchange 中有一些对 DBFREAD 函数的引用 但它不再可用 真的有问题吗 我确实有数据库工