Code covered by the BSD License  

Highlights from
GetFullPath

4.6

4.6 | 11 ratings Rate this file 59 Downloads (last 30 days) File Size: 17.1 KB File ID: #28249

GetFullPath

by

 

21 Jul 2010 (Updated )

Full path name for partial or relative path

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

| Watch this File

File Information
Description

GetFullPath - Get absolute path of a file or folder name

This function converts a partial or relative name to an absolute full path name. The fast Mex works on Windows only, but the M-file runs on Windows, MacOS and Unix.

FullName = GetFullPath(Name, Style)
INPUT:
  Name: String or cell string, file or folder name with relative or absolute path.
         UNC paths accepted. Path need not exist.
  Style: Special styles for long file names under Windows:
          'auto': Add '//?/' for long names (> 255 characters).
          'lean': No '//?/'.
          'fat': '//?/' added for short names also.
         Optional, default: 'auto'.
         
OUTPUT:
  FullName: String or cell string, file or folder name with absolute path.

EXAMPLES:
  cd(tempdir); % Assuming C:\Temp here
  GetFullPath('File.Ext') % ==> 'C:\Temp\File.Ext'
  GetFullPath('..\File.Ext') % ==> 'C:\File.Ext'
  GetFullPath('.\File.Ext') % ==> 'C:\Temp\File.Ext'
  GetFullPath('*.txt') % ==> 'C:\Temp\*.txt'
  GetFullPath('D:\Folder1\..\Folder2') % ==> 'D:\Folder2'
  GetFullPath('\') % ==> 'C:\', current drive!
  GetFullPath('Folder\') % ==> 'C:\Temp\Folder\'
  GetFullPath('\\Server\Folder\Sub\..\File.ext')
  % ==> '\\Server\Folder\File.ext'

Alternatives:
  WHICH: only for existing files, ~24 times slower.
  System.IO.FileInfo: .NET (thanks Urs), more features, ~50 times slower.
  java.io.File: "/.." and "/." are fixed by getCanonicalPath (~6 times slower),
      but no completing of partial/relative path.

Tested: Matlab 6.5, 2008a, 2009a, 2011b, WinXP/32, Win7/64
Installation: See Readme.txt

Suggestions and question by email or in the comment section are very welcome.

Acknowledgements

This file inspired Icc Mex Tools and Natural Order Filename Sort.

MATLAB release MATLAB 7.13 (R2011b)
Other requirements Mex for Windows, M for Linux/MacOS
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (25)
24 Mar 2014 Igor

@Charles: About using "c" instead of "m" - have you tried other submissions, providing similar functionality? Have you tested their performance? As far as I can remember, when I was looking for such a function some time ago, I noticed many "m" implementations were quite slow. Most of them are quite unstable as well. I was happy to find this one - fast and quite reliable. Probably the best of it's kind for Matlab. It's still not perfect, for example, see my comments below. I've voted "5" because it's better that others, not because it's "perfect".
I do strongly agree that it's ridiculous that programmer should think about these things when using such a high-level language.

23 Mar 2014 Jan Simon

@Charles: Microsoft decided not to support path names with more than 260 characters along time ago. The consequences are cruel, e.g. file with such full path names cannot be thrown to the recycle bin in the Windows Explorer and a drag&drop copy to a network drive is not possible also. A lot of other API functions are affected by this restriction. The C-extension allows to use at least one reliable method of the operating system, which can handle even Unicode character sets correctly. But notice, that even the native GetFullPathName API function of Windows does not insert the required \\?\ automatically on demand. Therefore I cannot find any block of code, which can be removed from my function without removing necessary features.

Providing an additional M-file to support Unix and platform independent programs is a fair idea in the FEX. And I have never seen a software, which has been tested too exhaustively.

It is not the question, how much time is spent inside this function, but how much debug time is required to identify and fix errors caused by unusual path names, which are not treated correctly.

Counting code lines -including comment lines and test code- is a strange method to assess the code quality. If you think, you can write some code, which offers the same functionality with less lines, you are invited to do so and publish it here also. You can find more submissions here for this topic, but they consider less exceptions. Therefore I'm still convinced, that this is considered high quality code. Of course, I'd be glad, if such a function is included in Matlab already.

I appreciate any constructive feedback, but "this is more complicated than I expect" is not a helpful criticism, because this depends mainly on your expectations and not on the code.

23 Mar 2014 Charles

I downvoted because of the code quality. There are no less than 831 lines of code across all the m and c files (including tests). 831 lines. For a function that returns the absolute path of a file. Really. Is this really what is considered high quality MATLAB code? A C extension was necessary for this? How much time in your MATLAB code is spent computing the absolute path? Enough to merit writing a C extension? I have a hard time believing that.

23 Mar 2014 Jan Simon

@Charles: I do not see a reason for down-rating, because it is not my fault that there is no built-in function yet.

16 Mar 2014 Charles

It's very concerning that this amount of MATLAB code AND a C extension is needed to get the absolute path of a file AND that this became Pick of the Week. A 30-year-old language still has no native function to get the absolute path of a file.

06 Mar 2013 Vinay Kumar Tadepalli  
27 Jan 2013 Igor

If anyone wants to lower the length limit at which GetFullPath generates UNC path, this tiny modification seem to work:

Just under line 86:
-------------------
#include <wchar.h>
-------------------

add the following two lines:
-------------------
#undef MAX_PATH
#define MAX_PATH 230
-------------------

(To test it with ease, one may firstly limit MAX_PATH to, say, 20; and check if GetFullPath would return
--------------------------------------
>> GetFullPath('c:\123456789123456789')
ans =
\\?\c:\123456789123456789
--------------------------------------
).

25 Jan 2013 Jan Simon

@Igor: Thanks for your comments. Even with 257 or 256 some problems remain, e.g. MKDIR requires a path with less than 248 characters (why?):
str = ['C:\Temp\', repmat('abcdefghkl\', 1, 23)]
mkdir(p(1:248)) % Error: filename or extension is too long
The long path cannot be created in the Windows Explorer or deleted to the recycler.
Therefore I still think, that these are limitations of DIR and MKDIR, and it isn't a good idea to include the workarounds in GetFullPath. Enhanced DIR and MKDIR commands would be more efficient and direct.
But to go a step further: Actually this is a problem of Windows, which still suffers from this ridiculous limitations which have been comprehensible in the pre-NTFS times only.

You are welcome to change the limit in the code to 257, and I'm convinced there will still be problems and inconsistencies as for all other limits also. Therefore I'd prefer improved file handling functions instead of adjusting GetFullPath.

25 Jan 2013 Igor

Thanks for the update!
Though, some Matlab functions (like "dir") still fail for 258-long path on my R2012b.

Example:
Just create a directory like this anyhow:

p = 'C:\temp\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\ufolder4'

then:

>> isdir(p)
ans =
1
>> exist(p)
ans =
7
>> length(p)
ans =
258
>> dir(p)
'C:\temp\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\ufolder4' not found.
>> isequal(GetFullPath(p),p)
ans =
1
>> dir(GetFullPath(p)
dir(GetFullPath(p)
|
Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.

>> dir(GetFullPath(p))
'C:\temp\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\abcdefghkl\ufolder4' not found.
>> dir(['\\?\' p])

. ..

====================
So, maybe it's worth changing the limit to, say, 257 characters?

07 Sep 2012 Julian

Thanks, very useful; I too have needed this but run into trouble in various ways so never been fully satisfied with my solution. I don't fully understand the C-windows API method, but looks like it is working on my PC... For preparation of paths I can get away with cd(cd('/the/path/string'))...

19 Apr 2012 Jan Simon

Thanks Igor! There is another problem if the the full path has 254 characters. While Windows accept this, Matlab's DIR command doesn't. I'm going to post an improved version soon.

14 Apr 2012 Igor

It looks like I've found another bug - if one try to use an 255+ long UNS path as GetFullPath argument, (for example: nested GetFullPath) this may result in duplicate prefix, i.e. invalid filename.

---------------------------------------
K>> GetFullPath('I:\ROSPAN International\Suzunskoye field\Well 969\X-ray micro-CT\1. Suzun 82180-82181\Tfit\\incomplete\smp_w_fdiff 2012-04-13 20.43.59\\fit_Tall_IR\/fit_Tall_IR_2(inscribed square)//unaligned//Histograms0001/errorbar_runmean_mask (vol1-vol2)_vs_mean(vol1(mask))')
ans =
\\?\I:\ROSPAN International\Suzunskoye field\Well 969\X-ray micro-CT\1. Suzun 82180-82181\Tfit\incomplete\smp_w_fdiff 2012-04-13 20.43.59\fit_Tall_IR\fit_Tall_IR_2(inscribed square)\unaligned\Histograms0001\errorbar_runmean_mask (vol1-vol2)_vs_mean(vol1(mask))
K>> GetFullPath( GetFullPath('I:\ROSPAN International\Suzunskoye field\Well 969\X-ray micro-CT\1. Suzun 82180-82181\Tfit\\incomplete\smp_w_fdiff 2012-04-13 20.43.59\\fit_Tall_IR\/fit_Tall_IR_2(inscribed square)//unaligned//Histograms0001/errorbar_runmean_mask (vol1-vol2)_vs_mean(vol1(mask))'))
ans =
\\?\UNC\?\I:\ROSPAN International\Suzunskoye field\Well 969\X-ray micro-CT\1. Suzun 82180-82181\Tfit\incomplete\smp_w_fdiff 2012-04-13 20.43.59\fit_Tall_IR\fit_Tall_IR_2(inscribed square)\unaligned\Histograms0001\errorbar_runmean_mask (vol1-vol2)_vs_mean(vol1(mask))
K>>

23 Mar 2012 Oscar  
27 Feb 2012 Kiran  
09 Dec 2011 Paul Sexton

I was having the same problem as Daniel (with the 01May2011 version). Using the 03Nov2011 version fixes that behavior.

Running the tests on Linux (32-bit) still breaks though:

>> uTest_GetFullPath
==== Test GetFullPath 09-Dec-2011 14:21:31
Function: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/GetFullPath.m
Current path: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011

ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011, Folder: [Folder/]
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011, File: File
ok: ../Folder/
ok: ../../Folder/
ok: ../../../Folder/
ok: ../../../../Folder/
ok: ../../../../../Folder/
ok: ../File
ok: ../../File
ok: ../../../File
ok: ../../../../File
ok: ../../../../../File
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../Folder/
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../Folder/
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../Folder/
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../../Folder/
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../../../Folder/
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../File
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../File
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../File
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../../File
ok: /home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/../../../../../File
Path: [/home/psexton/Documents/MATLAB/GetFullPath_03Nov2011/..] ==> error
GetFullPath replied: [/home/psexton/Documents/MATLAB]
Expected: [home/psexton/Documents/MATLAB]
Error using uTest_GetFullPath (line 202)
Error using uTest_GetFullPath (line 196)
uTest_GetFullPath: GetFullPath with folder failed

04 Nov 2011 Jan Simon

@Daniel: I've tried to improve the code, but cannot test it under Linux.

17 Oct 2011 Daniel

I am not sure this works on Linux ...
GetFullPath('/home/test/../')
gives /ho/home/

20 Aug 2011 Igor  
01 Mar 2011 Eugeny Sosnovsky  
02 Aug 2010 Oliver Woodford

Yes, the non-mex version (which I didn't originally see) is very good.

27 Jul 2010 Jan Simon

@Oliver: Or use the shipped M-version, which runs on Win/MacOS/Linux, considers the cases "C:", "..", "." and "~/", and does not change the current path.
If you comment out the warning about the unfound MEX, GetFullPath.m is 2.5 times faster than FULLPATH for files without path, and 40 times faster for file with a realtive or full path (WinXP, 2009a).

26 Jul 2010 Oliver Woodford

For those people wanting a function that works across platforms, doesn't require mexing, and who don't care so much about speed, an alternative is:
http://www.mathworks.com/matlabcentral/fileexchange/23603-fullpath

22 Jul 2010 Jan Simon

Thanks Urs! The doc is fixed.

22 Jul 2010 us

jan

this should be corrected
- System.IO.FileInfo is a .NET component (available only in more recent ML versions)
- java.io.File is the java class

urs

22 Jul 2010 Thomas Schreiter

Exactly what I needed.
I included this GetFullPath into my setup files which prepare the Matlab paths. And now these paths do not contain '\..' anymore. Effect: Matlab uses only one path for a file instead of multiple, which had confused the debugger.

Updates
22 Jul 2010

Doc updated, function not touched.

27 Jul 2010

M-Version replied bad path for input with leading separator. GetFullPath('\') is the current drive on Windows.

31 Jan 2011

Accept cell strings as inputs.

31 Mar 2011

Bugfix in M-version: Treat empty matrix as empty string.

01 May 2011

Minor bug: '***' in the ErrorID caused bad messages in case of errors.

03 Nov 2011

C-Mex tested under Win7/64. Improved UNC path support in the M-file. Bugfix for M-file under Linux (thanks Daniel).

17 Jan 2013

Improved handling of inputs with '//?/' prefix. 2nd input to control prefix in the output. New InstallMex function.

Contact us