필터 지우기
필터 지우기

Fully resolving path names

조회 수: 287 (최근 30일)
Ray
Ray 2012년 12월 12일
댓글: Kyle Kaja 2024년 4월 17일 22:55
Objective: retrieve and store an absolute (or fully-qualified) path name for a file or directory from a user specified string which could be given as absolute, relative to a MATLAB path, relative to the current working directory ('.' or '..'), or relative to a user's directory (~ or ~user).
Builtin functions like EXIST and WHICH do a great job of searching out files that are on the path, hidden in class folders, specified as relative to the current directory, ... but they do not robustly return the full path for generic files (i.e. non-MATLAB user files that may not be on the MATLAB path). WHICH has a somewhat nonsensible behavior of claiming a file that EXIST, DIR, and FOPEN can find does not exist.
The goal is to be able to robustly obtain the absolute path name for a file so that it can be found again even from a different working directory or with a different MATLAB path.
For now my solution is to confirm existence of the file (EXIST) then save both the specified filename and the current working directory. Assuming that the MATLAB path doesn't change, I can cd to the directory, execute FOPEN, and then cd back whenever I need to access the file. Neither clean nor efficient.
Ideally I would like a function absolutePath = resolvePath(filename) that uses the same search criteria as the builtin functions.
Thoughts?

답변 (6개)

Ray
Ray 2012년 12월 12일
Not a complete solution for all the smart places the builtin's look, but a useful snippet that should work for most user file and directory applications:
function fullpath = resolvePath(filename)
file=java.io.File(filename);
if file.isAbsolute()
fullpath = filename;
else
fullpath = char(file.getCanonicalPath());
end
if file.exists()
return
else
error('resolvePath:CannotResolve', 'Does not exist or failed to resolve absolute path for %s.', filename);
end
  댓글 수: 1
Alec Jacobson
Alec Jacobson 2023년 8월 8일
This doesn't seem to work correctly for paths starting with ../ on mac. It always thinks the current directory is ~/Documents

댓글을 달려면 로그인하십시오.


Jan
Jan 2012년 12월 12일

Jurgen vL
Jurgen vL 2020년 6월 18일
Using the python os submodule to get an absolute path:
string(py.os.path.realpath(py.os.path.expanduser(<PATH>)))
The above does not yet check if the absolute path exists. Requires python to be installed and discoverable by MATLAB.
  댓글 수: 1
Alec Jacobson
Alec Jacobson 2023년 8월 8일
First call is slow (launching python?) but subsequent calls are fast and this works for paths starting with / , ~/ and ../

댓글을 달려면 로그인하십시오.


Andrea Barletta
Andrea Barletta 2020년 11월 6일
I had a similar question and I realized it was easier than I thought. I am sharing my code, just in case (no Java or Python used). I should work on all versions >=R2017b.
function absPath = getAbsPath(obj)
getAbsFolderPath = @(y) string(unique(arrayfun(@(x) x.folder, dir(y), 'UniformOutput', false)));
getAbsFilePath = @(y) string(arrayfun(@(x) fullfile(x.folder, x.name), dir(y), 'UniformOutput', false));
if isfolder(obj)
absPath = getAbsFolderPath(obj);
elseif isfile(obj)
absPath = getAbsFilePath(obj);
else
error('The specified object does not exist.');
end
  댓글 수: 6
Andrea Barletta
Andrea Barletta 2020년 11월 10일
Unfortunately I am unable to test my function on any version older than R2018a, for which I can confirm it works. I have some (unconfirmed) confidence it also works in version R2017b as I wrote in my first post. It will certainly not work on previous versions as some dependencies would be missing (e.g. isfolder).
Walter Roberson
Walter Roberson 2020년 11월 10일
However, the remaining part of the code needs to be there to address files other than folders, as per original request. Furthermore, dot notation is to be preferred to getfield according to the official documentation:
Yes, dot notation is preferred. However, Tom Hawkin's version using getfield() can be implemented in a single call without making any assignments, and assignments used to be strictly necessary in order to use dot notation without using getfield() or subsref().
Starting in R2019b, you can use dot notation to index the result of a function call, such as
dir('.').folder
However, dir() of a folder returns entries for the folder and its parents and everything directly inside of the folder, so dir('.').folder would be certain to return an expansion into a minimum of two (identical) entries. If you were passing the result into something, you would probably get complaints about too many inputs. For example
>> length(dir('.').folder)
Error using length
Too many input arguments.
getfield(dir('.'), 'folder') would return only a single copy, but using dot notation as "preferred" would have to deal with the multiple copies, such as
struct('folder', unique({dir('.').folder})).folder
But more likely
First = @(varargin) varargin{1};
First(dir('.').folder)
Though of course you could also do
FirstFolder = @(dinfo) dinfo(1).folder;
FirstFolder(dir('.'))

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2012년 12월 12일
Pull off the file-name part. cd() to what remains. pwd() to find out the directory name. cd() back.
  댓글 수: 2
Ray
Ray 2012년 12월 12일
Thanks for the input. Your suggestion does solve some of the issues. However, if the input string is relative to the current working directory, one of the MATLAB paths, or one of the other nooks and crannies that EXIST and other builtins check, your solution will fail because there is no where to CD.
Kyle Kaja
Kyle Kaja 2024년 4월 17일 22:55
Once you have the file name part stripped off, here's a simple way to do the directory changes:
resolvedPath = cd(cd(dirPath));
This takes advantage of the fact that cd() returns the previous working directory, therefore avoiding the need to call pwd().

댓글을 달려면 로그인하십시오.


Gavriel Aminov
Gavriel Aminov 2023년 1월 18일
Please examine my File Exchange contribution: Convert local to remote (global) filename.

카테고리

Help CenterFile Exchange에서 File Operations에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by