目录路径变量应该以斜杠结尾吗?

当将目录的路径定义为变量或常量时,是否应以斜杠结尾?大会是什么?

Unix 中的 pwd显示你的工作目录没有尾部斜杠,而完整的 cd /var/www/apps/标签包括尾部斜杠,这让我不确定。

50149 次浏览

Whenever I store directory paths or return them from APIs, I try and stick with the convention of keeping a trailing slash. This avoids the whole 'is it a file or a directory' ambiguity.

Addendum:
This is not intended to be a substitute for using methods that can tolerate either a trailing slash or its absence. Even using this convention I still always use Path.Combine(...) and similar methods.

I tend to just add the trailing slash as I am more than likely going to use that directory to add/retrieve files...

In terms of web referencing, it can actually increase performance leaving the trailing slash in

http://www.netmechanic.com/news/vol4/load_no11.htm

I've never seen a firm convention either way.

Pretty sure, though, that whatever you settle upon, someone else will be 100% sure it should be the other way. So, the best idea is to tolerate things being set either way.

In the .NET world, Path.Combine() gives you a way to handle this - there are equivalents in other environments, from cmd files on up.

I don't include the trailing slash when I, for example, define a directory for storing files. That is because I will use it like

$store_file = "$store_path/$file_id";

I will always add a trailing slash before using a variable that's supposed to hold a directory path. I think it's better to always add one than to wonder if the trailing slash is included.

Yes, it should, as:

Pathname + filename = fully qualified file location.

SO the slash between the last directory and the filename needs to be either at the end of the pathname or the start of the filename. Prefixing filenames with a / means you need to take this into account if you just want to open a file (i.e if you assume that an unqualified filename is in the current working directory).

Yes, there are lots of filesystems that support files without any extensions, so always add the trailing slash to avoid any problems.

I go with the trailing slash because:

  1. "If it ends with a slash, it's a directory. If not, it's a file." is an easy convention to remember.

  2. At least on the operating systems I commonly use, doubling the slash causes no problems, while omitting the slash causes big ones. It is, therefore, safest to both put the slash into the variable and use "$path/$file" when making use of it.

Maybe you should think about what your decision would mean for files. If you don't include the trailing slash at the end of a directory name you'll have to add it to the start of the file name.

Now, if for some reason, the path leading up to the file is missing when you concatenate strings, you end up with something like /filename which is not just a file but an absolute path from the root directory (wherever that may be in that context).

That's why I end my paths with a slash and keep files as files.

I know this is an old thread but I thought I'd share what I do. If possible, I'd normally allow for both and do something like this (if it was PHP):

$fullPath = rtrim($directory, '/') . '/filename.txt');

That way, if the directory is defined in a config file, it doesn't matter whether the next person to change it includes the trailing slash or not.

In php, since dirname(__FILE __) function returns the directory name without a slash at the end. I tend to stick to that convention.

Otherwise, using a slash at the end of a directory name will conflict with the way dirname(..) works and then you are stuck with handling the two cases since you don't know if the directory name came from a dirname(..) function or a content defined with a trailing slash.

Bottom Line: Don't use a trailing slash since dirname(..) doesn't.

// PHP Example
dirname(__FILE__); // returns c:\my\directory without a trailing slash, so stick to it!

For other languages, check the function that extracts a pathname, and see if it is using a trailing slash or not, then stick to the language's convention.

I know that this is 10 years old, but I wanted to throw in my very opinionated $0.02.

No. No. Absolutely no.

We are talking about a Unix system. In reference to the directory itself, it is a node like any other. When referring to the directory, it should not ever have an unescaped slash in its name (ref: dirname, pwd, ~, echo $HOME, echo $PATH, the output from ls, et al).

When referring to a directory's contents, then you need a slash. That is to say, ls /home/karl/ is more appropriate than ls /home/karl (FTR, I almost always do the latter because ...well, lazy).

When utilizing a variable containing a directory to create the full path to a file, you would always expect to include the slash (i.,e: cp ${HOME}/test ${OTHER_DIR}/).

It is expected that a directory not end in a slash. Any expectation that a directory ends in a slash is wrong. Thus adding a slash to the end of a *_DIR variable's value would be subverting expectations.

As for tab completion, the expectation here is that you are going into that directory. Thus, the assistance provided by tab completion is to get you into that directory so that you can make the next choice based on its contents.

(reference from comments: Filepath Misconceptions, from Wikipedia's Talk:Path_(computing) page. Thanks, john c. j.)

It is worth noting that just because it is wrong doesn't mean that tools/packages/libraries never do it. It is a far-too-common occurrence that such things add a trailing slash when none should exist. Therefore, as Bevan and Paul F both suggested, when using 3rd party tools, it is best to remove any trailing slashes that might exist in directory names.

Unix Inodes

The inode (index node) is a data structure in a Unix-style file system that describes a file-system object such as a file or a directory.

-- https://en.wikipedia.org/wiki/Inode

Filesystem Hierarchy Standard

The standard for the Unix filesystem (the Filesystem Hierarchy Standard, AKA FHS) clearly show that directories are not thought of as having a trailing slash, but rather directory contents begins with a slash (the only exception to this is / because we will not refer to the filesystem root by using an empty string ...and one should never be creating files there anyway.)

-- http://www.pathname.com/fhs/pub/fhs-2.3.html

-- https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

I guess this is one of those rare cases where the correct theoretically and practically answer is different.

It seems @Karl Wilbur's answer for sure is correct in a theoretical sense, as you should be able to distinguish a reference to the directory node itself from the directory's content.

But in practice I'll argue the correct answer is the opposite:

  • The most important reason is you can tell with certainty that the path /home/FSObjectX/ is a folder, whereas /home/FSObjectX is ambiguous. No one can tell if this is a file of folder.
    Specifications shall always be precise and unambiguous whenever possible.

  • In a vast majority of cases, you will always reference the content of a folder, not the dir node itself.
    In those rare cases where you actually do, it can easily be handled in the code by removing any optional trailing dir-separator.

  • Using double dir-separators will not do any harm, although missing one will for sure.
    In theory a bad argument as your shouldn't code by "chance", but in practice, errors happen, and perhaps using trailing dir-sep might end up with a few fewer runtime errors at an end-user.

Reading through this interesting thread I haven't found any disadvantages of using trailing dir-sep, only that it's wrong in a theoretical sense. Or did I miss something?

The convention is to be consistent. Importantly, realise that the argument as to whether the / belongs to the directory or the filename is a false dichotomy; it belongs to neither because it is a path separator.

The correct answer, IMO, is where possible you should use path manipulation libraries if they are provided by your language (or write your own), and ignore the internal structure of a path just because it looks like a string. This will eliminate the problem of knowing where to put the slash, and also make your code more portable between systems.