What is the longest directory and file name? - windows

I need to optimize my Java application that works with directories and files. I use String[] buffer; to keep file or dir name. So what's the longest possible file or dir name allowed in Windows 8.1?

Filename with path to the file is limited to 260 characters.

Related

*.* as pattern for folders and files

In batch file scripts and the doc pages (e.g. here) I often see *.* as (I guess) a way to specify multiple folder/ file names. My question is: How exactly this string *.* is interpreted by cmd.exe?
I know that specify folder/ file names two special characters can be used:
* means any number of character (including zero)
? one character
So *.txt would mean all files with extension .txt in the current directory. In light of this, I would read *.* as any folder/file name that has . (dot) in it.
Why then when I run DIR *.* in a folder that has only a subfolder named folder and a file named script.txt, it displays folder and script.txt instead of just showing script.txt?

Why does cmd DIR search include files that start with the 3 searched letters but then differ?

If in a directory I have two files, test.pro and test.properties, and I run dir /s *.pro to find all files with the .pro extension, it lists both files. However, when I run dir /s *.pr, it lists neither. Why does searching for a three-letter file extension list files with extensions that start with the three letters? How can I search for ONLY .pro files using dir?
The command DIR lets the file system search for file system entries (file names, directory names, reparse points (links)) matching the wildcard pattern *.pro in long name or in short 8.3 name on short name management also enabled for the file system of current drive.
The short file name of test.pro is TEST.PRO.
The short file name of test.properties is TEST~1.PRO.
Therefore the wildcard pattern *.pro matches test.pro and TEST~1.PRO displayed with long file name test.properties.
The wildcard pattern *.pr does not match with the two file names because of the file extension is pro respectively properties and not just pr. The wildcard pattern *.pr? would also find the file names test.pro and TEST~1.PRO displayed with long file name test.properties.
There can be used %SystemRoot%\System32\where.exe /R . *.pro to find recursively in current directory and all its subdirectories files with file extension .pro not matching file names with a longer file extension beginning with pro because of WHERE applies the wildcard pattern only on long file names.
DIR and also FOR use the Windows file I/O function which directly searches with the wildcard pattern *.pro for suitable file system entries. WHERE uses the Windows file I/O function to search for * to get a list of long names of all file system entries and then applies the wildcard pattern itself on each string returned by the file system. For that reason the usage of the wildcard pattern *.pro returns a positive result only on test.pro and not on test.properties on using WHERE.

Where is the use of "\\?\" defined?

This command is to delete all files and sub-folders in a folder
rd /s "\\?\D:\TestFolder
This command snippet got from a youtube video right here
Could someone explain what this, \\?\, does?
It's the prefix to bypass Windows path normalization. With it you'll be able to access paths that are not valid in Win32 namespace like names ending with . or spaces: D:\TestFolder\folder ending with space \file name ending with dot., or files with path longer than MAX_PATH (260 characters in older Windows)
For file I/O, the "\\?\" prefix to a path string tells the Windows APIs to disable all string parsing and to send the string that follows it straight to the file system. For example, if the file system supports large paths and file names, you can exceed the MAX_PATH limits that are otherwise enforced by the Windows APIs. For more information about the normal maximum path limitation, see the previous section Maximum Path Length Limitation.
Naming Files, Paths, and Namespaces - Win32 File Namespaces
See
Dots at the end of file name?
How to copy files that have too long of a filepath in Windows?

Recursively copy file-types from directory tree

I'm trying to find a way to copy all *.exe files (and more, *.dtd, *.obj, etc.) from a directory structure to another path.
For example I might have:
Code
\classdirA
\bin
\classA.exe
\classdirB
\bin
\classB.exe
\classdirC
\bin
\classC.exe
\classdirD
\bin
\classD.exe
And I want to copy all *.exe files into a single directory, say c:\bins
What would be the best way to do this?
Constraints for my system are:
Windows
Can be Perl, Ruby, or .cmd
Anyone know what I should be looking at here?
Just do in Ruby, using method Dir::glob :
# this will give you all the ".exe" files recursively from the directory "Code".
Dir.glob("c:/Code/**/*.exe")
** - Match all directories recursively. This is used to descend into the directory tree and find all files in sub-directories of the current directory, rather than just files in the current directory. This wildcard is explored in the example code.
* - Match zero or more characters. A glob consisting of only the asterisk and no other characters or wildcards will match all files in the current directory. The asterisk is usually combined with a file extension, if not more characters to narrow down the search.
Nice blog Using Glob with Directories.
Now to copy the files to your required directory, you need to look into the method, FileUtils.cp_r :
require 'fileutils'
FileUtils.cp_r Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
I just have tested, that FileUtils.cp method will also work, in this case :
require 'fileutils'
FileUtils.cp Dir.glob("c:/Code/**/*.exe"), "c:\\bins"
My preference here is to use ::cp method. Because Dir::glob is actually collecting all the files having .exe extensions recursively, and return them as an array. Now cp method is enough here, now just taking each file from the array and coping it to the target file.
Why I am not liking in such a situation, the method ::cp_r ?
Okay, let me explain it here also. As the method name suggests, it will copy all the files recursively from the source to target directory. If there is a need to copy specific files recursively, then ::cp_r wouldn't be able to do this by its own power ( as it can't do selections by itself, which ::glob can do ). Thus in such a situation, you have to give it the specific file lists, it would then copy then to the target directory. If this is the only task, I have to do, then I think we should go with ::cp, rather than ::cp_r.
Hope my explanation helps.
From cmd command line
for /r "c:\code" %f in (*.exe) do copy "%~ff" "c:\bins"
For usage inside a batch file, double the percent signs (%% instead of %)
Windows shell (cmd) command:
for /r code %q in (*.exe) do copy "%q" c:\bin
Double the % characters if you place this in a batch file.

If I have the name of a file, how do I search a folder for a file that contains that filename?

I have an image with the filename media_httpfarm3static_mAyIi.jpg.
I would like to search the parent folder and all subfolders of that parent folder for a file that contains that name - it doesn't have to be the EXACT name, but must contain that string.
E.g. this file should be returned: 11605730-media_httpfarm3static_mAyIi.jpg
So this is a 2-part question:
How do I achieve the above?
Once I have the file, how do I return the path for that file?
Use Dir::[] and File::absolute_path:
partial_name = "media_httpfarm3static_mAyIi.jpg"
Dir["../**/*#{partial_name}"].each do |filename|
puts File.absolute_path(filename)
end
This uses the glob "../**/*media_httpfarm3static_mAyIi.jpg" (go up one directory, then search all sub directories (recursively), for any file ending in the partial string "media_httpfarm3static_mAyIi.jpg". The relative paths are then returned in an Array.
You can use Array#each, Array#map, etc. to convert this into what you need. To convert a relative path, into an absolute path, just pass it to File::absolute_path.
Once you have the absolute path, you can use it to open the file, read the file, etc.
On File Paths
The glob "../**/*media_httpfarm3static_mAyIi.jpg" is relative to the current working directory. Normally, this is the directory from which the program was run. Not the directory of the source file. This can change using various utilities to change it.
To always use a glob relative to the source code file, try:
Dir[File.expand_path('../**/*#{partial_name}', __FILE__)]
You can also use:
Dir[File.join(__dir__, "..", "**", "*#{partial_name}")]
Note: __dir__ was added in Ruby 2.0. For older versions of ruby use File.dirname(__FILE__)
In the first code sample File::absolute_path was used. In the last sample File::expand_path is used. In most situations these can be used interchangeably. There is a minor difference, per the documentations:
File::absolute_path
Converts a pathname to an absolute pathname. Relative paths are
referenced from the current working directory of the process unless
dir_string is given, in which case it will be used as the starting
point. If the given pathname starts with a “~” it is NOT expanded, it
is treated as a normal directory name.
File::expand_path
Converts a pathname to an absolute pathname. Relative paths are
referenced from the current working directory of the process unless
dir_string is given, in which case it will be used as the starting
point. The given pathname may start with a “~”, which expands to the
process owner’s home directory (the environment variable HOME must be
set correctly). “~user” expands to the named user’s home directory.

Resources