If you pass in 'ReturnOnError',false with the textscan call, there will be an error message where the format cannot read your file. That's likely due to the missing data.
readtable tries to read using a detected format, and when that fails updates to re-read with a new format. It may be slow because it's reading multiple times trying to get the format correct. You could pass that same formatSpec into readtable, but it will likely error in the same way as textscan (just not silently)
If you try detectImportOptions with the file, then readtable, you might have faster/better results.
opts = detectImportOptions(file,'Delimiter','|','ExpectedNumVariables',47)
tp = preview(file,opts)
fmt = split(formatSpec(2:end),'%');
opts = setvartype(opts,strcmp(fmt,'f'),'double');
opts = setvartype(opts,strcmp(fmt,'s'),'char');
T = readtable(file,opts);
I can't really test this without your file, but it should work (maybe with some tweaking)