JAVA解析TDMS文件

article/2025/9/11 21:43:47

2023年更新:

没想到还有人关注,上传了最新代码
https://github.com/yc97/TDMSDecoder
该代码经过测试,基本没什么bug了

 

reference:

http://www.eefocus.com/Junking/blog/12-07/281264_7bf69.html

http://www.ni.com/white-paper/14252/zhs/

http://www.ni.com/white-paper/5696/en/

http://liuhao815.blog.163.com/blog/static/2314297820091016113039903/

https://github.com/yc97/TDMSDecoder

本人项目中软件是用java写的,Swing做的界面(BTW:Swing真的是丑,而且美化界面的资料实在是少啊,克服了很多困难才完成,相关技术总结在写,先挖坑),然后需要对LabVIEW保存的TDMS文件进行解析,NI公司主推的文件格式,但是貌似只在NI软件里面流行,使用其他语言解析的资料确实不多,他有C库,可是我的软件要运行多种系统,用C写的话想着也很麻烦。最后看到了Github上有一个java写的TDMS解析项目,于是参考了一下他的基本思路,针对自己的项目修改了很多,然后用到了自己的代码里,在这里表示感谢。在这里总结一下相关知识

1技术背景:

1.1TDMS文件逻辑结构:

TDMS(Technical DataManagement Streaming)文件是NI主推的一种二进制记录文件,它兼顾了高速、易存取和方便等多种优势,能够在NI的各种数据分析或挖掘软件之间进行无缝交互,也能够提供一系列API函数供其它应用程序调用。

TDMS的逻辑结构分为三层:文件(File)、通道组(Channel Groups)和通道(Channels),如图 1所示,每一个层次上都可以附加特定的属性(Properties)。程序员可以非常方便地使用这三个逻辑层次定义测试数据,也可以任意检索各个逻辑层次的数据,这使得数据检索是有序的、方便存取的。

图1 TDMS文件的逻辑结构

       1.2 TDMS文件二进制结构

TDMS文件的内部结构(二进制结构、物理结构)如图2所示。TDMS内部结构的核心是segment,当数据被写入到segment中时实际上是新建了segment。各个segment中包含的主要数据段的含义如下所示:

Ø  ToC Bitmask:这是一个32位的整型数据段,它表示该segment是否包含meta data、raw data。

Ø  Version number:表示segment的版本,这可以确保兼容一些旧的TDMS文件版本。

Ø  Next segment offset:表示下一个segment的偏移字节。

Ø  Raw data offset:表示Raw data的偏移字节。

Ø  Meta Data:三个层次的属性存储字段。

Ø  Raw data:实际的raw data存储字段。

这种物理结构也就决定了TDMS文件的随机存取特性,当程序员只希望读取raw data而并不关注属性时,此时可以利用raw data offset直接获得raw data信息而无需关注Meta Data信息。正如前面所述,往TDMS中添加信息时实际上是添加了新的segment,因此无需关心segment之前的内容是什么,也就确保了写TDMS文件的速度与TDMS文件的大小无关,保证了高速存取。值得注意的是,TDMS物理结构中的segment与其三层次逻辑结构没有任何关系。可能一个通道对应着多个segment,也可能一个segment中包含多个通道。当把数据写入硬盘时就是产生一个segment,而把数据从硬盘中读取出来时也就是把一个个的segment内容读取出来。

图2 TDMS文件的物理结构

2技术简介

通过上述介绍,可以知道通过二进制的方式读取TDMS文件,需要依次读取segment,然后解析segment的内容。

       基本的读取流程如下图所示:

由于文件是按照二进制存储的,需要对每个字节进行解析,每个部分的数据格式不尽相同,因此,在读取以上数据的时候,需要TDMS文件支持的数据类型有所了解。

2.1数据类型

以下是数据类型的结构与说明

typedef enum {
    tdsTypeVoid,//空类型
    tdsTypeI8,//有符号整型8位    
    tdsTypeI16, //有符号整型16位   
    tdsTypeI32, //有符号整型32位   
    tdsTypeI64, //有符号整型64位
    tdsTypeU8, //无符号整型8位     
    tdsTypeU16, //无符号整型16位   
    tdsTypeU32, //无符号整型32位   
    tdsTypeU64, //无符号整型64位
    tdsTypeSingleFloat, //单精度浮点     
    tdsTypeDoubleFloat,  //双精度浮点  
    tdsTypeExtendedFloat,    
    tdsTypeSingleFloatWithUnit=0x19,    
    tdsTypeDoubleFloatWithUnit,    
    tdsTypeExtendedFloatWithUnit,
    tdsTypeString=0x20, //字符串  
    tdsTypeBoolean=0x21,  //布尔型 
    tdsTypeTimeStamp=0x44, //时间戳
    tdsTypeFixedPoint=0x4F,
    tdsTypeComplexSingleFloat=0x08000c,
    tdsTypeComplexDoubleFloat=0x10000d,
    tdsTypeDAQmxRawData=0xFFFFFFFF
} tdsDataType;

    在TDMS文件读取过程中,需要通过按照相应的长度读取相应的数据类型并转换成所需要的数据。以下是各个结构的详细说明:

2.1 Lead In

    Lead In结构的详细描述见下表

二进制结构 (16进制)

描述

54 44 53 6D

"TDSm" tag

0E 00 00 00

ToC mask 0x1110 (segment contains object list, meta data, raw data)

69 12 00 00

Version number (4713)

E6 00 00 00 00 00 00 00

Next segment offset (value: 230)

DE 00 00 00 00 00 00 00

Raw data offset (value: 222)

 

    前四个字节是字符串“TDSm”文件标识;接下来四个字节是Toc(Table of Contents)掩码,指示了segment中是否含有Metadata和RawData等信息;接下来四个字节是该文件的版本信息;接下来8个字节指示了下一个segment的位置;最后8个字节指示了RawData的位置。

2.2 Meta Data

  • segment中对象的数量(4个字节)
  • 对象路径字符串(表格中的表头)的长度length(4个字节)
  • 对象路径字符串(length个字节)
  • Raw data index指示RawData的类型(4个字节)
  • 属性properties的数量 (4个字节)
  • 属性,包含
    • 属性名称(string)
    • 属性的数据类型
    • 属性值
    • 在读取过程中,我们通过一个全局的Channel类型的数组来进行保存属性对象

2.3 Raw Data

    这一部分是我们最关心的数据,根据RawDataIndex来解析数据类型之后,也保存在Channel类型的数组中。

最终,我们获取到若干个Channel类型的数据,进行解析后即可得到存入的数据。

在了解以上知识的基础上,参考github上一个java解析TDMS的项目

https://github.com/yc97/TDMSDecoder

这个项目已经好久没动静了,虽然基本思路很正,但是不适用我的TDMS文件,存在很多问题,然后我对其进行修改完善,用到了自己的代码里

 写的不够详细,后续再写


http://chatgpt.dhexx.cn/article/BgE2voLO.shtml

相关文章

LabVIEW写入可快速加载的TDMS文件

LabVIEW写入可快速加载的TDMS文件 TDMS文件格式的设计目的是在尽可能快地读写数据的同时仍保持足够的灵活性来适应采集过程中通道数量和采样率的变化。 但是数据读写速度快的文件未必可快速加载。 TDMS文件是一个完全的二进制文件,由多个部分数据段组成,…

LabVIEW TDMS连续写入内存增长

LabVIEW TDMS连续写入内存增长 每次执行TDMS写入VI时,内存(RAM)使用量都会略有增加。这是内存泄漏吗,如何防止内存使用量增加? 解答 此问题有几种可能的解决方案: TDMS文件的引用可能没有适当地关闭。对…

Matlab查看tdms文件

由于最近项目需要使用Labview开发解调设备,对于高速采集卡就需要使用tdms存储数据(存储的数据量较大),而用matlab无法对tdms格式文件进行直接读取,所以查找一些相关博客,解决了读取的问题。(以下…

Labview数据存储与读取——TDMS文件的创建与写入

Labview数据存储与读取——TDMS文件的创建与写入 你好,这是我在自学Labview编写软件过程中使用的一些功能。我在存储采集卡数据时,通过阅读大量他人的程序,发现TDM及TDMS文件十分适合波形数据的记录,TDMS文件比TDM文件在存储动态…

TDMS转EXCEL

NI官方有推出TDMS转EXCEL插件,安装后可直接用excel打开tdms文件。 下载链接:https://download.csdn.net/download/Kleds_Love/81168914 下载为iSO文件,右键→装载→管理员身份安装即可 安装完成后,直接双击tdms文件,…

计算TDMS文件的THD

1.用采集卡采集一路正弦信号,存为.tdms文件 2.将.tdms文件转成.csv文件或.txt文件或.xlsx文件,使MATLAB可以将数据导入工作空间 法1:将.tdms文件转成.csv文件(依靠LabVIEW程序) 法2:将.tdms文件转成.txt文件…

如何打开tdms文件

1、下载一个插件 地址:https://www.ni.com/example/27944/en/ 2、下载后按照导向安装即可 3、安装后如果不能打开文件,试试重启电脑,或者你电脑上没有execl软件

用Matlab处理TDMS数据(降噪+频谱分析)

目录 TDMS文件从导入到最终处理的整个过程第一:把TDMS文件导入到matlab用MATLAB TDMS函数使用ConventTDMS函数 第二:把Matlab的数据画出来附录:1-照着步骤依然显示不了图的解决办法附录:2-使用Matlab批量转换".TDMS"文件…

labview的TDMS文件读写

文章目录 一概念介绍1.相关概念2.tdms文件介绍 二.VI介绍1.TDMS打开VI2.TDMS写入3.TDMS读取4.TDMS设置属性5.TDMS获取属性6.TDMS关闭 三.范例分析——TDMS文件 并行读写的操作 写在最前面:本文先介绍TDMS概念和文件结构,然后介绍VI如何使用,最…

插件框架篇一之scrollbars

问题:部分手机(如三星)ListView或GridView设置scrollbars显示时会报错奔溃。 问题分析: ScrollView继承于View,在View的构造器中初始化scrollbars。 根据initializeScrollbars判断是否需要进行scrollbars初始…

VBA,窗体和控件的动态效果之一:scrollbar如何实现自动效果

问题由来:静态和瞬时的效果不够用,窗体的动态效果更难实现 之前只学习了窗体的静态效果现在考虑 窗体和控件的动态效果 1 srcollbar如何实现自动效果 给 Button 2 绑定了这样一个sub点击后,Scroll Bar 1 可以自动变化注意点:因为…

C#开发串口小助手(可更改波特率、串口号,可实现数据以及字符的收发)

0. 前言 前置项目为:VS 2019中利用C#语言在.Net Framework 4.5框架上开发简易串口发送数据软件本项目的全部代码已经放置至码云:https://gitee.com/jiawei_zh/serial_assistant本项目参考杜洋工作室:入门C#设计。 1. 项目实现 1.1 配置For…

android RecyclerView 添加可拖动的滚动条

实现的效果图如下,为了效果这里我设置的宽了一些,实际根据需求修改即可 先说几个属性: android:scrollbars" 一般都是垂直的滚动条设置vertical android:scrollbarSize 设置滚动条的宽度 android:scrollbarThumbVertical:…

基于机智云的Android开源app修改教程

前言 首先,这是我最近搞的毕业设计,然后为了使自己的app更加的有个人风格,故在网上寻找了很多的参考资料,这里是对自己设计的总结,具体机智云APP生成流程请参考我上一篇博客。链接: 基于stm32的连接机智云教程 机智云…

Android中修改ScrollBar默认样式

好吧,又遇到需求了,需要修改ScrollBar的样式,于是查阅了很多文档,觉得这位大牛总结的不错,顺便看了下他的主页,哇哦,大神啊~!!!附上大神文章的链接&#xff1…

RecyclerView实现可拖动滚动条并修改宽度

本文参考了孤调的文章,链接如下: https://www.jianshu.com/p/67e1df2b1920 基本实现了拖动的需求,但是还有一个问题就是滚动条的宽度跟需求不符,需要进行修改.但是官方并未提供相应的参数.自己动手丰衣足食,开始撸源码. 打开RecyclerView类,搜索fastScrollEnabled,定位到构造方…

IDEA修改配置

1.修改 bin/idea.properties---------------主要是把路径放开 # Use ${idea.home.path} macro to specify location relative to IDE installation home. # Use ${xxx} where xxx is any Java property (including defined in previous lines of this file) to refer to its v…

利用ajax修改删除页面数据,使用Jquery的Ajax实现无刷新更新,修改,删除页面

本文将向大家讲述一下最近工作的一些总结,主要包括了以下内容,注册界面以及详细信息界面的编辑。主要是介绍了AJAX技术,因为我觉得其他方面没什么好介绍的。首先是跟大家说一下Ajax的优点,假如你删除了一个页面的内容,…

代码修改RecyclerView的scrollbar颜色

因为scrollbar是view的私有内部类,所以需要动态修改RecyclerView的scrollbar颜色, 只能通过反射获取scrollbar的drawable,然后用反射着色,亲测可用,代码直接粘贴就可使用。 import android.content.Context; import an…

lvgl v8之Styling the scrollbars

Styling the scrollbars /** * Styling the scrollbars */ static void lv_example_scroll_4(void) {lv_obj_t* obj lv_obj_create(lv_scr_act()); // 创建obj对象lv_obj_set_size(obj, 200, 100); // 设置大小lv_obj_center(obj); // 居中显示lv_obj_t* label lv_…