sco1
sco1

Reputation: 12214

System dir call to network drive prunes file path

Apologies in advance for not being able to provide a completely reproducible example, not everyone is going to have a network drive to experiment with.

I have a processing function that I'm using to perform data reduction and our data is stored on a network drive. while debugging this morning I discovered something strange (to me) and I'm curious to know why Windows (Win7, 64 bit) behaves this way. My Google-fu has been defeated.

As an example, say I have this file structure on \\mynetworkshare

\\mynetworkshare\testdata\a
\\mynetworkshare\testdata\b
\\mynetworkshare\testdata\c
\\mynetworkshare\testdata\c\day1
\\mynetworkshare\testdata\c\day2

With somedatafile_n.abc in each of the day folders.

My function parses through the user specified folder, c in this case, and looks for all of the data files that match the filter:

searchpath = '\\mynetworkshare\testdata\c'
oldpath = cd(searchpath); % cd to data directory for simpler dir call
[~, filenames] = system('dir /S /B somedatafile_*.abc');
filelist = regexp(filenames, '(.:\\[\w\-\\. ]+\.\w+)', 'match'); % Split filenames
cd(oldpath);

This returns a cell array of filenames:

Z:\day1\somedatafile_1.abc
Z:\day1\somedatafile_2.abc
Z:\day2\somedatafile_1.abc

However, these are not valid paths to use with low level I/O:

Error using textscan
Invalid file identifier. Use fopen to generate a valid file identifier.

It should be noted that this functions correctly if I mount the network drive and use that path instead:

searchpath = 'H:\testdata\c'
oldpath = cd(searchpath); % cd to data directory for simpler dir call
[~, filenames] = system('dir /S /B somedatafile_*.abc');
filelist = regexp(filenames, '(.:\\[\w\-\\. ]+\.\w+)', 'match'); % Split filenames
cd(oldpath);

Which returns:

H:\testdata\c\day1\somedatafile_1.abc
H:\testdata\c\day1\somedatafile_2.abc
H:\testdata\c\day2\somedatafile_1.abc

Upvotes: 0

Views: 1370

Answers (2)

Hoki
Hoki

Reputation: 11812

If you are only using cd and dir to get a list of file names which you can later open in Matlab, you don't need to use a dos command.

The Matlab function ls can do that for you. And you don't even have to change your working directory ;-)

I've created a directory structure and files according to your example on a shared drive:

folders

Then without resorting to external command, you can get a list of the files you are interested in by:

baseShareName = '\\CASTOR\SharedFolder\testdata' ;

%// let's get the folder list in a variable (but you can easily hard code it if you prefer
folderList = cellstr( ls(baseShareName) ) ; %// cellstr wrapping call otherwise the output is a char array

%// return the file names of interest in the folder #5 (which is "c")
fileList = ls( [baseShareName '\' folderList{5} '\somedatafile*.abc'] )          %'// ignore this comment

%// and/or if you prefer to get the full length name (valid for later "fopen")
fullNameList = fullfile( baseShareName , folderList{5} , cellstr(fileList) )

Will give you:

fileList =
somedatafile_01.abc
somedatafile_03.abc

fullNameList = 
    '\\CASTOR\SharedFolder\testdata\c\somedatafile_01.abc'
    '\\CASTOR\SharedFolder\testdata\c\somedatafile_03.abc'

And these file names are totally ok to use with Matlab low level I/O functions:

>> fid = fopen( fullNameList{1} , 'r' )
fid =
     3

3 is a valid file identifier which will work with any Matlab file operating function.

Upvotes: 1

PersyJack
PersyJack

Reputation: 1974

From https://www.mathworks.com/help/matlab/ref/system.html

DOS does not support UNC path names. Therefore, if the current folder uses a UNC path name, then running system with a DOS command that relies on the current folder fails. To work around this limitation, change the folder to a mapped drive before calling system.

system('net use Z: \\mynetworkshare\testdata\c')
cd('Z:\')
fileID = fopen('day1\somedatafile_1.abc');
C = textscan(fileID,'%s %s %f32 %d8 %u %f %f %s %f');
fclose(fileID);

Upvotes: 5

Related Questions