Problem with textscan when file doesn't exist.

In my program I check if there is stored information on the user in userdata.txt. When the file doesn't exist yet I get the error:
??? Error using ==> textscan
Invalid file identifier. Use fopen to generate a valid file identifier.
At line:
data = textscan(fid,'%s%s%s');
Here is the relevant code:
if ~exist('userdata.txt','file')
new = fopen('userdata.txt','w');
fclose(new);
end
fid = fopen('userdata.txt','r');
data = textscan(fid,'%s%s%s');
fclose(fid);

2 comentarios

Adam
Adam el 14 de Dic. de 2017
Why are you trying to read data from a file you have only just created which has nothing in it?
Adam Hicks
Adam Hicks el 14 de Dic. de 2017
Editada: Adam Hicks el 14 de Dic. de 2017
@Adam I added a default line for it to read as I test against the data later on and would rather not rewrite all of that code when I could add a few lines here.
THE SOLUTION
Ultimately my problem was that MATLAB was somehow opening a version of my program which wasn't changing and the one I was changing apparently didn't exist. I closed both, opened the original and ended up adding my code as a function:
function data = getUserData
if isempty(dir('userdata.txt'))
new = fopen('userdata.txt','w');
fprintf(new,'%s\r\n',['user' ' ' 'First' ' ' 'Last']);
fclose(new);
end
fid = fopen('userdata.txt','r');
data = textscan(fid,'%s%s%s');
fclose(fid);
end
which I call in place of the original code. Everything works now and next time I'll make sure MATLAB isn't doing something strange like this with my files.

Iniciar sesión para comentar.

 Respuesta aceptada

Rik
Rik el 14 de Dic. de 2017

0 votos

Either insert a check if the file exists (use exist('userdata.txt','file')), or wrap this in a try-catch block. I would advise the first.

5 comentarios

Adam Hicks
Adam Hicks el 14 de Dic. de 2017
I thought " if ~exist('userdata.txt','file') " served as a check? Is it possible that I need to add a wait function for the file to exist before continuing?
Ah, sorry, I misread your code. It does serve as a check, but simply opening it apparently doesn't yet generate a file. You need to move the read to the else block.
if ~exist('userdata.txt','file')
data={};
else
fid = fopen('userdata.txt','r');
data = textscan(fid,'%s%s%s');
fclose(fid);
end
It still gives me the same error as if it is completely ignoring the if statement with file creation. I switch to using isempty(dir('userdata.txt')) in the if statement because 'userdata.txt' existed in another directory within my current working directory.
if isempty(dir('userdata.txt'))
new = fopen('userdata.txt','w');
fprintf(new,'%s\r\n',['user' ' ' 'first' ' ' 'last']);
fclose(new);
end
fid = fopen('userdata.txt','r');
data = textscan(fid,'%s%s%s');
fclose(fid);
I proved that isempty(dir('userdata.txt')) gives an output of 1 and the opening, printing, and closing creates a file, but it still ignores this and gives me the same error. Putting the textscan section in an else block didn't do anything either. I tried using uiwait to wait for the file to be created as well. I am at a loss.
Adam Hicks
Adam Hicks el 14 de Dic. de 2017
I solved the problem which turned out to be an issue with MATLAB opening an unedited version of my program. Thanks for your help, you were probably correct the entire time.
Rik
Rik el 14 de Dic. de 2017
I always try to provide an explicit path to avoid these things. You can get the path to the folder this script is in by using dbstack('-completenames'), or using one of many other options, including this FEX submission: find_containing_folder. With fileparts you can easily move up the folder tree if you need to.

Iniciar sesión para comentar.

Más respuestas (1)

Guillaume
Guillaume el 14 de Dic. de 2017
It would be interesting to know under which circumstances your code generates the error. The code does not make much sense, but should not generate an error.
If the file does not exist, the code creates an empty one, which it'll then read. Of course, since the file is empty, so will be data.
Note that while testing for the existence of a file before opening works in most cases, it's not robust. There are plenty of reasons why a file might exist at the point where you test for its existence but not anymore when you actually open it, even if it's on the next line. Antivirus, OS background operations, network disk going down, some other process moving the file, etc. may make the file disappear.
A better way is to simply catch the failure and respond appropriately.
fid = fopen('userdata.txt', 'r');
try
data = textscan(fid, '%s%s%s');
fclose(fid);
catch
msg = ferror(fid);
if ~isempty(msg)
disp(['Failed to read or open file because: ' msg]);
end
end
which will cope with more problems than just the file not existing (e.g. you don't have read permission on the file).

Categorías

Más información sobre Large Files and Big Data en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 14 de Dic. de 2017

Comentada:

Rik
el 14 de Dic. de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by