Matlab批量提取子文件夹simass.txt数据写入文件仅存单个值问题排查
问题根源与修复方案
核心问题:文件打开模式错误
嘿,我一眼就发现问题所在了——你每次循环处理文件时,都用'w'模式打开features.txt。这个模式的作用是创建新文件(如果不存在)或直接清空已有文件再写入新内容,所以每处理一个文件,之前写入的数据就被彻底覆盖了,最终自然只剩最后一个提取到的值!
两种修复思路
思路1:使用追加模式边处理边写入
如果想保持边处理边写入的逻辑,可以把文件打开模式改成'a'(追加模式),这样每次写入都会把内容加到文件末尾,不会覆盖之前的内容。另外建议在循环开始前先清空features.txt,避免多次运行脚本时内容累加:
修改后的关键代码片段:
% 循环开始前先清空目标文件(可选,确保每次运行都是全新结果) filePh = fopen('features.txt','w'); fclose(filePh); % 处理每个文件的循环内 filePh = fopen('features.txt','a'); % 改用追加模式 fprintf(filePh, '%s\n', cellvalue); % 加换行符保证每个值单独占一行(单列) fclose(filePh);
思路2:先收集所有数据再一次性写入(更高效)
对于1000个文件的场景,频繁打开关闭文件会影响效率,更优的做法是先把所有提取到的值存到一个数组里,最后一次性写入文件:
修改后的完整代码示例:
clc; % Clear the command window. workspace; % Make sure the workspace panel is showing. format long g; format compact; % Define a starting folder wherever you want start_path = fullfile(matlabroot, 'D:\Tools\Parameter Generation\'); % Ask user to confirm or change. topLevelFolder = uigetdir(start_path); if topLevelFolder == 0 return; end % Get list of all subfolders. allSubFolders = genpath(topLevelFolder); % Parse into a cell array. remain = allSubFolders; listOfFolderNames = {}; while true [singleSubFolder, remain] = strtok(remain, ';'); if isempty(singleSubFolder) break; end listOfFolderNames = [listOfFolderNames singleSubFolder]; end numberOfFolders = length(listOfFolderNames) % 初始化cell数组存储所有提取的值 allValues = cell(numberOfFolders, 1); % Process all text files in those folders. for k = 1 : numberOfFolders % Get this folder and print it out. thisFolder = listOfFolderNames{k}; fprintf('Processing folder %s\n', thisFolder); % Get filenames of all TXT files. filePattern = sprintf('%s/simass.txt', thisFolder); baseFileNames = dir(filePattern); numberOfFiles = length(baseFileNames); % Now we have a list of all text files in this folder. if numberOfFiles >= 1 % Go through all those text files. for f = 1 : numberOfFiles fullFileName = fullfile(thisFolder, baseFileNames(f).name); fileID=fopen(fullFileName); c=textscan(fileID,'%s%s%s','Headerlines',10,'Collectoutput',true); fclose(fileID); %celldisp(c) % display all cell values cellvalue=c{1}{2,3}; allValues{k} = cellvalue; % 将值存入数组 fprintf(' Processing text file %s\n', fullFileName); end else fprintf(' Folder %s has no text files in it.\n', thisFolder); allValues{k} = ''; % 空文件夹存入空字符串,避免数组缺失 end end % 最后一次性写入features.txt filePh = fopen('features.txt','w'); fprintf(filePh, '%s\n', allValues{:}); % 每个值单独占一行,实现单列效果 fclose(filePh);
额外优化提示
- 确保单列显示:一定要在
fprintf里加上\n换行符,这样每个提取的值才会单独占一行,符合你“单列”的需求。 - 避免递归子文件夹:
genpath会获取所有层级的子文件夹(包括子文件夹的子文件夹),如果你只需要处理topLevelFolder下的一级子文件夹,可以把获取文件夹列表的代码改成:
% 获取一级子文件夹 listOfFolderNames = dir(topLevelFolder); listOfFolderNames = {listOfFolderNames([listOfFolderNames.isdir]).name}; % 去掉.和..两个默认文件夹 listOfFolderNames = listOfFolderNames(~ismember(listOfFolderNames, {'.', '..'})); % 拼接完整路径 listOfFolderNames = fullfile(topLevelFolder, listOfFolderNames);
这样就只会处理直接子文件夹,避免意外处理深层嵌套的文件夹。
内容的提问来源于stack exchange,提问作者user6985
相关产品推荐
相关产品推荐

