Can Spaces Exist Within A File Extension?
I'm currently working with some code involving saving a file to a user-defined file. If the user passes in a filename with no extension, the code autodetects the extension based on the file type (stored internally).
However, I'm having a hard time determining whether the filename passed to the code has an extension or not. I'm using Path.HasExtension(filename)
and Path.GetExtension(filename)
but it seems to be exhibiting strange behavior:
File.EXT
=> .EXT
is the extension. This is fine.
This Is A File.EXT
=> .EXT
is the extension. This is also fine.
This Is A File. Not An Extension
=> . Not An Extension
is the extension. However, I would think of this as a file without an extension. Windows thinks so too when I create a file with this name (creating a file with an unrecognized extension causes windows to call it a EXTENSIONNAME File
, whereas files without an extension such as this one are just called File
).
This Is A File.Not An Extension
=> .Not An Extension
is the extension. Same problem as above.
Also note that this same behavior is evident in Path.GetFileNameWithoutExtension(filename)
(e.g. it reports the filename without extension on the last two examples to be just This Is A File
).
So what I'm taking from this is that .NET and Windows differ on what they think of as an extension.
The Question: I'm wondering if it's OK for me to implement code such as this:
if(!Path.H开发者_开发百科asExtension(filename) || Path.GetExtension(filename).Contains(" ")) {...}
since that would pull my code's definition of a proper extension more in line with how Windows treats things. Or is there something I'm missing here which explicitly says I must allow spaces in my extensions?
I've searched and found this slightly similar question, but the documents linked therein only specify that it's not recommended to end the extension with a space/period -- they say nothing about spaces within the extension.
The extension on a filename in Windows is purely a convention. The GetExtension
and HasExtension
methods only look for a dot in the filename and act accordingly. You are free to put spaces anywhere you like within the filename (including the extension).
When you say "Windows thinks so too", it's really just some code in Explorer that tries to parse out extensions, and it simply uses a slightly different algorithm than .NET.
How the filesystem handles names and how the Windows shell (i.e. Explorer) handles file names are two completely different beasts.
The filesystem doesn't care about spaces, dots or anything else -- to it, the filename is just one opaque string (with some restrictions on allowed characters). The name/extension separation is just a made-up convention. The shell, on the other hand, is free to make up its own interpretation of what an extension is because its purpose is not to store and retrieve file information but rather to provide the user with a better experience. So don't go looking there for answers.
I would suggest going with what the System.IO
methods return (because following the convention is good), but you can do whatever you like in your code if there's a good reason for it.
There is no official definition of what an extension is. The common convention is that everything after the final .
is the extension.
However if you would grab a HUGE list of all common-used extensions I think you'll only find a handful of examples where spaces in an extension are used.
I would say, disallow spaces in extensions. 999/1000 times the user didn't mean it as an extension.
To quote Wikipedia on filenames:
. (DOT): allowed but the last occurrence will be interpreted to be the extension separator in VMS, MS-DOS and Windows. In other OSes, usually considered as part of the filename, and more than one full stop may be allowed.
精彩评论