TDM和TDMS是一種NI的資料儲存檔案格式,兼顧速度、邏輯組織。對於此格式資料檔案,NI提供的第三方庫使用也很便捷。關於TDM和TDMS的更多敘述,請自行google、百度,或者去官網瞭解。這裡主要給出第三方庫的簡單使用,及經過自己的測試,得到的關於TDM和TDMS格式的效率結論。

       NI提供的第三方庫使用時配置環境十分簡單,把標頭檔案、動態庫佈置好就行,讀寫檔案的例子如下(從官網下載第三方庫帶的也有例子):

//寫TDM/TDMS格式檔案
int CTDMSTestDlg::WriteDDCFile(const char* filePath, int channelNum, int dataLen, const char* fileType /* = "TDM" */)
{
    DWORD begin = ::GetTickCount();
    DDCFileHandle testFile;
    DDC_CreateFile(filePath, fileType, "", "", "", "", &testFile);//建立指定格式的檔案
    DDCChannelGroupHandle group01;
    DDC_AddChannelGroup(testFile, "group01", "", &group01);//增加一個通道組
    DDCChannelHandle* channels = new DDCChannelHandle[channelNum];
    double* channelData = CreateRandomData(dataLen);
    for (int i = 0; i < channelNum; i++)
    {
        char channelIdx[20];
        itoa(i, channelIdx, 10);
        DDC_AddChannel(group01, DDC_Double, channelIdx, "", "", &channels[i]);//增加一個通道,注意每次增加通道時,第三個引數的值要不一樣,否則會覆蓋
        DDC_SetDataValues(channels[i], channelData, dataLen);                   //為新增的通道設定資料
    }
    DDC_SaveFile(testFile);
    DWORD end = ::GetTickCount();
    DDC_CloseFile(testFile);
    delete[] channels;
    delete[] channelData;
    return end - begin;
}
//讀TDM/TDMS格式檔案
int CTDMSTestDlg::ReadDDCFile(const char* filePath, const char* fileType/* = "TDM"*/)
{
    DWORD begin = ::GetTickCount();
    DDCFileHandle ddcFile;
    DDC_OpenFile(filePath, fileType, &ddcFile);//開啟檔案
    unsigned int groupNum = 0;
    DDC_GetNumChannelGroups(ddcFile, &groupNum);//獲取通道組的數目
    DDCChannelGroupHandle* groups = new DDCChannelGroupHandle[groupNum];
    for (int i = 0; i < groupNum; i++)
    {
        unsigned int channelNum = 0;
        DDC_GetNumChannels(groups[i], &channelNum);//獲取通道的數目
        DDCChannelHandle* channels = new DDCChannelHandle[channelNum];
        for (int j = 0; j < channelNum; j++)
        {
            unsigned __int64 dataLen = 0;
            DDC_GetNumDataValues(channels[j], &dataLen);//獲取資料長度
            double* data = new double[dataLen];
            DDC_GetDataValuesDouble(channels[j], 0, dataLen, data);//獲取double型別資料
            for (int k = 0; k < dataLen; k++)
            {
                data[k];
            }
        }
        delete[] groups;
        groups = NULL;
    }
    DWORD end = ::GetTickCount();
    DDC_CloseFile(ddcFile);
    delete[] groups;
    return end - begin;
}

       可以看出,讀寫TDM和TDMS檔案是非常方便的。

       但是TDM和TDMS格式有什麼區別呢?查過很多資料,最直接的最表象的區別就是,TDM有個XML頭,其他資料用二進位制儲存,而TDMS的索引啊資料啊都是二進位制檔案。看官網的介紹,我一直以為TDMS格式是比較提倡的。後來做實驗發現好像不是這麼回事,我得到的結論如下(不侷限於兩者的區別,還包括別的結論,另外也不保證一定對,但是可以作為參考,大家相互討論):

       1、在通道數和每個通道的資料長度相同時,TDM和TDMS格式產生的檔案是差不多大小的;

       2、在通道數和每個通道的資料長度相同時,TDM和TDMS格式寫入資料時,TDMS格式寫資料總是比TDM格式花費的時間多將近一倍,讀取資料的時間都差不多(兩者都有索引,在多次讀取資料時,花費的時間會比第一次花費的時間少,不過TDMS格式在多次訪問後的讀取時間始終比TDM格式的要多一點點);

       3、通道數目增加到10000這個級別的時候,寫資料花費的時間明顯增加很多,但是資料長度的增加和寫資料所花費的時間基本呈線性比例;

       4、注意寫入資料時要留足空間!這個第三方庫產生的中間檔案比最終的資料檔案大小還要大很多,比如12G左右的資料檔案可能需要至少32G以上的空間。不過如果資料量不大的話,比如128個通道,資料長度為102400,最終資料大小為100M,不算很大,中間檔案需要的空間也就不是很大,無需擔心了。

       程式碼自行下載,使用VS2008。http://down.51cto.com/data/919272 或者 http://pan.baidu.com/share/link?shareid=112939018&uk=1007352492