Code covered by the BSD License  

Highlights from
FileRealCase

FileRealCase

by

 

Get real upper/lower case of a file or folder name

FileRealCase(File)
function FileName = FileRealCase(File)
% Get correct case of file or folder by repeated calls of DIR
% FileName = FileRealCase(FileName)
% INPUT:
%   FileName: String with an absolute path of an existing file or folder.
%             UNC paths are accepted.
% OUTPUT:
%   FileName: String, absolute path with upper/lower case as set in the file
%             system. Drive letters are in upper case.
%             The server and shared folder of UNC-paths cannot be adjusted.
%
% Matlab remembers the path as accessed in under Windows:
%   pathname = upper(fileparts(which('plot.m')));
%   % >> C:\PROGRAMME\MATLAB651\TOOLBOX\MATLAB\GRAPH2D
%   cd(pathname)
%   which('plot.m')
%   % >> C:\PROGRAMME\MATLAB651\TOOLBOX\MATLAB\GRAPH2D\plot.m
%   FileRealCase(which('plot.m'))
%   % >> C:\Programme\Matlab651\toolbox\matlab\graph2d\plot.m
%
% NOTE: Because Linux and MacOS uses case-sensitive filesystems, I assume this
%   function is useful under Windows only. But Linux file separators are
%   considered at least, if somebody finds a useful application.
%
% NOTE: Matlab's WHICH can find the correct case of files inside the Matlab path
%   also. But this fails for files in the current folder, if the folder was
%   selected using a string with wrong case.
%
% Tested: Matlab 6.5, 7.7, 7.8, WinXP, Linux
% Author: Jan Simon, Heidelberg, (C) 2009-2011 matlab.THISYEAR(a)nMINUSsimon.de
%
% See also: DIR, FILEPARTS, FULLFILE.
% FEX: GetFullPath.

% $JRev: R-e V:004 Sum:w5H5zA2lZQp2 Date:10-Feb-2011 10:49:49 $
% $License: BSD - free use, copy, modify, redistribute; mention the author $
% $File: FileRealCase.m $
% History:
% 002: 14-Sep-2010 17:06, [UNC path: ok].
% 004: 06-Feb-2011 12:20, Published under BSD license.

% Initialize: ==================================================================
% Create the full path name for relative path:
% Download: http://www.mathworks.com/matlabcentral/fileexchange/28249
% File = GetFullPath(File);

% Check existence of the file or folder:
if exist(File, 'file') == 0
   error_local('MissingFile', 'File or folder does not exist.', File);
end

% Do the work: =================================================================
% Adjust file separators:
if ispc
   FSep = '\';
   File = strrep(File, '/', FSep);
else
   FSep = '/';
   File = strrep(File, '\', FSep);
end

% Split file to parts:
if sscanf(version, '%d', 1) >= 7
   List = regexp(File, FSep, 'split');
else  % Fallback for Matlab <= 6.5:
   List = Str2Cell_local(File, FSep);
end

% Number of parts - ignore trailing file separator:
nList        = length(List);
hasTrailFSep = isempty(List{nList});
if hasTrailFSep
   nList = nList - 1;
end

% Care for exceptions:
if strncmpi(File, '\\', 2)  % UNC path:
   if nList < 4
      error_local('IncompleteUNCPath', 'Incomplete UNC path.', File);
   end
   FileName   = ['\\', fullfile(List{3:4}), '\'];
   StartIndex = 5;
   
else   % No UNC path:
   FileName   = List{1};
   StartIndex = 2;
   
   % The drive needs a trailing file separator:
   if isempty(FileName)  % Unix root folder:
      FileName = FSep;
   elseif length(FileName) == 2 && FileName(2) == ':'  % Windows drive letter:
      FileName = [upper(List{1}), FSep];
   end
end

% Ask DIR about the correct case for all parts but the drive:
firstIter = true;
xSep      = '';
for iL = StartIndex:nList
   allDir  = dir(FileName);
   allName = {allDir.name};
   match   = find(strcmpi(allName, List{iL}));
   if length(match) == 1
      FileName = cat(2, FileName, xSep, allName{match});
      if firstIter
         firstIter = false;
         xSep      = FSep;
      end
      
   elseif isempty(match)  % No matching name found:
      error_local('MissingFile', 'File or folder does not exist.', File);
   else                   % Several matching names found:
      error_local('MultipleFile', 'File or folder name not unique.', File);
   end
end

% Append trailing file separator:
if hasTrailFSep
   FileName = fullfile(FileName, FSep);
end

return;

% ******************************************************************************
function CStr = Str2Cell_local(Str, Sep)
% Split string at separator - does not depend on the platform.
%   DATAREAD: not compatible to Matlab 2010b.
%   TEXTSCAN: not available in Matlab 6.5.
%   REGEXP('split'): not available in Matlab 6.5.
%   STRTOK:   Limited efficency.
%   A bunch of Str2Cell methods can be found in the FEX.

SepInd = strfind(Str, Sep);  % Find separators
if isempty(SepInd)
   CStr = {Str};
else
   % Append trailing separator on demand:
   StrLen  = length(Str);
   iSepInd = [1, SepInd + 1];
   if iSepInd(length(iSepInd)) > StrLen
      % Last iSepInd not used later
      fSepInd = SepInd - 1;
   else
      fSepInd = [SepInd - 1, StrLen];
   end
   nParts = length(fSepInd);
   
   % Copy each part into a cell element:
   CStr = cell(nParts, 1);  % Pre-allocate
   for iSep = 1:nParts
      CStr{iSep} = Str(iSepInd(iSep):fSepInd(iSep));
   end
   CStr(cellfun('isempty', CStr)) = {''};  % Avoid [1-by-0] strings
end

return;

% ******************************************************************************
function error_local(ID, Msg, File)
% Local error message
error(['JSimon:', mfilename, ':', ID], [Msg, '\nFile: "%s"'], File);

Contact us