如何在JavaScript中确定操作系统的路径分隔符?

118

在 JavaScript 中,我如何判断脚本所运行的操作系统使用的路径分隔符是什么?


当Javascript在浏览器中运行并具有完整的操作系统隔离时,为什么需要这个呢?你无法访问本地计算机上的文件... - lms
1
JavaScript通常在浏览器中运行,但并非总是如此。JavaScript在浏览器之外的一些用途包括Mozilla XULRunner应用程序、使用命令行解释器(如V8或WSH)运行的js脚本以及使用JScript编写的ASP页面。JS有许多用途。 - Joel Anair
我相信你已经解决了这个问题,但是我在下面添加了一个使用案例和答案,因为像你一样,我知道总有一种情况,你不能依赖操作系统来解决分隔符的问题!:)。干杯! - Decoded
2
这个问题非常相关,因为JavaScript经常在Node.js内运行。在那里,您可以并且想要访问文件系统,因此路径分隔符很重要。如果您想创建多OS Node.js应用程序,则这也是其中一个痛点。Node.js是多平台的,但这并不意味着任何Node.js程序都可以在所有支持的操作系统上运行,除非您特别注意所使用的文件路径。 - Panu Logic
6个回答

222
使用 node.js 中的 path 模块可以返回特定于平台的文件分隔符。
例如:
path.sep  // on *nix evaluates to a string equal to "/"

编辑:根据Sebas在下面的评论,要使用此功能,您需要在js文件顶部添加以下内容:

const path = require('path')

3
你可以改进你的答案,具体方式是指定 path.sep。参考链接:https://nodejs.org/docs/latest/api/path.html#path_path_sep。 - Ionică Bizău
13
const path = require('path'); - Sebas
虽然我知道在大多数情况下,如果不是全部情况,我都可以使用'/'。但是当我将输出打印到控制台以进行反馈或记录时,我喜欢在完整路径中使用相同的斜杠。 - b01
我认为上面是正确的答案,也是最简单的解决方案。正如Sebas所指出的那样,要访问path模块,你必须执行path = require('path')。如果你是一个Node程序员,即使是初学者,你可能已经知道这一点了。 - Panu Logic

29

在任何情况下,甚至在Windows系统中,您都可以使用“/”作为路径分隔符。

引用自http://bytes.com/forum/thread23123.html:

因此,情况可以简单地总结如下:

  • 从DOS 2.0开始,所有DOS服务和所有Windows API都接受正斜杠或反斜杠。这种方式一直存在。

  • 标准命令行解释器(CMD或COMMAND)都不接受正斜杠。即使在以前的帖子中给出了“cd ./tmp”示例,也会失败。


2
VVS的回答是正确的,但在解析Internet Explorer中文件输入给出的路径时有一个例外(已在IE8中测试 - 我不知道其他版本)。 在这种情况下,输入元素的值(input.value)给出的路径形式为“C:\ fakepath <filename>”。 注意这里的反斜杠。 - Milagre
1
顺便提一下:cmd.exe在Windows XP和Windows 7上都可以正确处理"cd /windows"(作为示例)。 - Eugene Mayevski 'Callback
4
这不是对所提出问题的完全正确回答...请参见下面的“正确答案” :)。 - Decoded
9
我对这个答案进行了负投票,因为它忽略了问题的完全合理性-即有些情况下确实需要知道正在使用的路径分隔符。例如,需要将路径拆分成多个部分时会使用该分隔符。 - MirroredFate
3
@VVS - 在同时使用两种类型的斜杠的情况下不起作用(至少在Windows 7上)。考虑这样一种情况,您正在使用__dirname构建变量,然后需要附加其余路径。例如:__dirname + '/images'。在该示例中,__dirname将使用特定于操作系统的斜杠,但是如果您尝试使用/images并且您在Windows上,则最终会得到类似c:\ somepath / images的路径,而这在Windows上不起作用。我刚遇到了这种情况,这就是为什么我提到它的原因 :)。 - dcp
访问 input type="file" 时,在不同的浏览器上工作不一致,现在通常会报告 C:\fakepath 前缀。因此,反斜杠代替了正斜杠。因此,如果您例如使用 split 获取基本名称进行解析,则无法获得所需内容。 - Volomike

17

正确答案

是的,所有操作系统都接受CD ../或CD ..\或CD ..无论您如何传递分隔符。但是,如果要读取路径,那该怎么办呢?例如,你如何知道它是一个具有允许' '\的“Windows”路径。

显而易见的问题

当你依赖于例如安装目录%PROGRAM_FILES% (x86)\Notepad++时会发生什么。看下面的例子。

var fs = require('fs');                             // file system module
var targetDir = 'C:\Program Files (x86)\Notepad++'; // target installer dir

// read all files in the directory
fs.readdir(targetDir, function(err, files) {

    if(!err){
        for(var i = 0; i < files.length; ++i){
            var currFile = files[i];

            console.log(currFile); 
            // ex output: 'C:\Program Files (x86)\Notepad++\notepad++.exe'

            // attempt to print the parent directory of currFile
            var fileDir = getDir(currFile);

            console.log(fileDir);  
            // output is empty string, ''...what!?
        }
    }
});

function getDir(filePath){
    if(filePath !== '' && filePath != null){

       // this will fail on Windows, and work on Others
       return filePath.substring(0, filePath.lastIndexOf('/') + 1);
    }
}

发生了什么!?

targetDir被设置为索引 00 之间的子字符串(C:\Program Files\Notepad\Notepad++.exeindexOf('/')-1),结果为空字符串。

解决方案...

这包括来自以下帖子的代码:如何在Node.js中确定当前操作系统

myGlobals = { isWin: false, isOsX:false, isNix:false };

服务器端操作系统检测。

// this var could likely a global or available to all parts of your app
if(/^win/.test(process.platform))     { myGlobals.isWin=true; }
else if(process.platform === 'darwin'){ myGlobals.isOsX=true; }
else if(process.platform === 'linux') { myGlobals.isNix=true; }

浏览器端的操作系统检测

var appVer = navigator.appVersion;
if      (appVer.indexOf("Win")!=-1)   myGlobals.isWin = true;
else if (appVer.indexOf("Mac")!=-1)   myGlobals.isOsX = true;
else if (appVer.indexOf("X11")!=-1)   myGlobals.isNix = true;
else if (appVer.indexOf("Linux")!=-1) myGlobals.isNix = true;

获取分隔符的辅助函数

function getPathSeparator(){
    if(myGlobals.isWin){
        return '\\';
    }
    else if(myGlobals.isOsx  || myGlobals.isNix){
        return '/';
    }

    // default to *nix system.
    return '/';
}

// modifying our getDir method from above...

获取父目录的帮助函数(跨平台)

function getDir(filePath){
    if(filePath !== '' && filePath != null){
       // this will fail on Windows, and work on Others
       return filePath.substring(0, filePath.lastIndexOf(getPathSeparator()) + 1);
    }
}

getDir()必须足够智能以知道它正在查找哪一个。

如果用户通过命令行输入路径等,您甚至可以变得非常聪明,并检查两者。

// in the body of getDir() ...
var sepIndex = filePath.lastIndexOf('/');
if(sepIndex == -1){
    sepIndex = filePath.lastIndexOf('\\');
}

// include the trailing separator
return filePath.substring(0, sepIndex+1);

如前所述,如果您想加载一个模块来执行这个简单的任务,您也可以使用“path”模块和path.sep。个人认为,仅检查已经可用的进程信息就足够了。

var path = require('path');
var fileSep = path.sep;    // returns '\\' on windows, '/' on *nix

就是这样啦,伙计们!


2
我喜欢你提供了查找分隔符并将其分解成可管理块的逻辑。这就是一个专业工程师的工作方式。对此给予加一。另外,考虑到问题的年龄和缺乏 NodeJS 标签 - 你回答了 服务器客户端 的两个方面。你的回答完全 - 实际上 - 回答了这个问题。对于 Node,我认为路径模块很好,因为它不会影响生成的字节码性能,也不应影响可读性(只有一个导入语句)。然而,你是唯一回答客户端的人。这应该被接受。 - Rik

10

如前面所述,您可以使用path.sep查找特定于操作系统的路径分隔符以手动构建路径。但是,当处理路径构造时,我更喜欢让path.join来完成这项工作,这是我的首选解决方案:

示例:

const path = require('path');

const directory = 'logs';
const file = 'data.json';

const path1 = `${directory}${path.sep}${file}`;
const path2 = path.join(directory, file);

console.log(path1); // Shows "logs\data.json" on Windows
console.log(path2); // Also shows "logs\data.json" on Windows

0
在JavaScript中,您可以通过window.navigator.userAgent获取此信息。

-7

只需使用“/”,据我所知,它适用于所有操作系统。


5
OP问的是如何“确定”,而不是哪个运算符适用于所有情况 :-) - Steel Brain
4
它能够运作,直到你需要解析路径以提取某些东西。 - Chris Seufert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接