在MATLAB中读取CSV文件中的特定十六进制数据

在MATLAB中读取CSV文件中的特定十六进制数据,matlab,Matlab,我浏览了StackOverflow上的帖子,似乎找不到我想要的答案。我有一个包含十六进制数据的大型CSV文件(450 MB),如下所示: 63C000CF,6000002F,603000AF,6000C06F,617300EF,6C7C001F,6000009F,0%,63C000CF... data = textscan(fid, '%s', 1, 'delimiter', '%'); data = textscan(data{1}{1}, '%s', 'delimiter', ',');

我浏览了StackOverflow上的帖子,似乎找不到我想要的答案。我有一个包含十六进制数据的大型CSV文件(450 MB),如下所示:

63C000CF,6000002F,603000AF,6000C06F,617300EF,6C7C001F,6000009F,0%,63C000CF...
data = textscan(fid, '%s', 1, 'delimiter', '%');
data = textscan(data{1}{1}, '%s', 'delimiter', ',');
data = data{1};

count = size(data);

outstring = ['%', sprintf('\n')];
for idx = 1:count(1)           
    string = data{idx};
    stringSize = size(string);
    if stringSize(2) > 1
        outstring = [outstring, string, sprintf('\n')];
    end
end
fprintf(output_fid, '%s', outstring)
这是一个非常截断的示例,但基本上我有大约78个不同的十六进制值,用逗号分隔,然后会有“0%”,然后再有78个十六进制值。这将持续很长时间。我一直在这样使用textscan:

63C000CF,6000002F,603000AF,6000C06F,617300EF,6C7C001F,6000009F,0%,63C000CF...
data = textscan(fid, '%s', 1, 'delimiter', '%');
data = textscan(data{1}{1}, '%s', 'delimiter', ',');
data = data{1};

count = size(data);

outstring = ['%', sprintf('\n')];
for idx = 1:count(1)           
    string = data{idx};
    stringSize = size(string);
    if stringSize(2) > 1
        outstring = [outstring, string, sprintf('\n')];
    end
end
fprintf(output_fid, '%s', outstring)
这使我能够以一种可以使用fgetl()分析是否正在查看所需数据的方式格式化csv文件。因为数据本身会重复,所以在再次调用fgetl()之前,我可以使用fseek()跳转到下一个事件


我需要的是一种跳到结尾的方式。我只希望能够使用类似fgetl()的东西,但让它只返回遇到的第一个十六进制值。我将知道要在文件中移动多少字节。然后我需要确保我可以读取其他十六进制值。我问的可能吗?我使用上面的文本扫描的代码在一个90 MB的csv文件上花费的时间太长了,更不用说450 MB了。

答案是从页面上的用户Cedric Wannaz获得的

新解决方案

这里有一个更有效的解决方案;我使用的是一个122MB的文件,所以你知道时间安排了

% One line for reading the whole file. To perform once only.
 tic ;
 content = fileread( 'adam_1.txt' ) ;
 fprintf( 'Time for reading the file    : %.2fs\n', toc ) ;
 % One line for defining an extraction function. To perform once only.
 extract = @(label) content(bsxfun( @plus, ...
                                    strfind( content, [label,','] ).' - 6, ...
                                    0 : 5 )) ;
 % Then it is one call per label to extract data.
 tic ;
 data = extract( 'CF' ) ;
 fprintf( 'Time for extracting one label: %.2fs\n', toc ) ;
运行这个,我获得

读取文件的时间:0.52秒

提取一个标签的时间:0.62s

前解

以下内容对你有用吗

 % Read file content. To do once only.
 content = fileread( 'myFile.txt' ) ;
 % Define regexp-based extraction function. To do once only.
 getByLabel = @(label) regexp( content, sprintf( '\\w{6}(?=%s)', label ), ...
                               'match' ) ;
 % Get all entries for e.g. label 'CF'.
 entries_CF = getByLabel( 'CF' ) ;
 % Get all entries for e.g. label '6F'.
 entries_6F = getByLabel( '6F' ) ;
我不完全清楚你最终需要实现什么;如果我必须设计一个GUI,用户可以在其中选择一个标签并获取相应的数据,我会在初始化阶段进一步处理数据,例如,通过在单元格数组中按标签对数据进行分组。我想,在这种情况下,Regexp不是最有效的方法,但原则是

 labels  = {'CF', '6F', 'AF', ..} ;
 nLabels = numel( labels ) ;
 data    = cell{ 1, nLabels ) ;
 for lId = 1 : nLabels
    data{lId} = getByLabel( labels{lId} ) ;
 end
然后当用户选择“CF”时

 lId = strcmpi( label, labels ) ;
 dataForThisLabel = data{lId} ;