¿Cómo determinar el separador de ruta del sistema operativo en JavaScript?

82

¿Cómo puedo saber en JavaScript qué separador de ruta se usa en el sistema operativo donde se ejecuta el script?

Angustia
fuente
¿Por qué necesita esto cuando Javascript se ejecuta dentro del navegador con aislamiento completo del sistema operativo? No puede acceder a archivos desde su computadora local ...
lms
JavaScript se ejecuta normalmente, pero no siempre, en el navegador. Algunos ejemplos de usos de JavaScript fuera del navegador son las aplicaciones Mozilla XULRunner, los scripts js que se ejecutan con un intérprete de línea de comandos como V8 o WSH y las páginas ASP escritas en JScript. JS tiene muchos usos.
Joel Anair
Estoy seguro de que ya resolvió el problema, pero agregué un caso de uso para su pregunta y una respuesta a continuación, porque al igual que usted, sé que siempre hay un caso en el que no puede depender del sistema operativo para resolver el problema. separador para ti! :). ¡Salud!
Decodificado
2
Esta pregunta es muy relevante porque JavaScript a menudo se ejecuta dentro de Node.js. Allí puede y desea acceder al sistema de archivos, por lo que el separador de ruta es importante. Este también es uno de los puntos débiles si desea crear aplicaciones Node.js. de varios sistemas operativos. Node.js es multiplataforma, pero eso no significa que ningún programa Node.js se ejecute en todos los sistemas operativos compatibles, sin que preste especial atención a las rutas de archivo que utiliza.
Panu Logic

Respuestas:

20

Es cierto que siempre puede usar / como separador de ruta, incluso en Windows.

Cita de http://bytes.com/forum/thread23123.html :

Entonces, la situación se puede resumir de manera bastante simple:

  • Todos los servicios de DOS desde DOS 2.0 y todas las API de Windows aceptan barra diagonal o barra invertida. Siempre tengo.

  • Ninguno de los shells de comando estándar (CMD o COMMAND) aceptará barras diagonales. Incluso el ejemplo "cd ./tmp" dado en una publicación anterior falla.

VVS
fuente
1
La respuesta de VVS es correcta, con la excepción de analizar una ruta dada por una entrada de archivo en Internet Explorer (probado con IE8; no sé sobre otras versiones). En este caso, la ruta proporcionada por el valor del elemento de entrada (input.value) tiene el formato "C: \ fakepath \ & lt; filename & gt;". Tenga en cuenta las barras invertidas aquí.
Milagre
JFYI: cmd.exe maneja "cd / windows" (como ejemplo) correctamente tanto en Windows XP como en Windows 7.
Devolución de llamada de Eugene Mayevski
2
Esta no es una respuesta completamente CORRECTA a la pregunta planteada ... consulte "La respuesta correcta" a continuación :).
Decodificado
5
Rechacé esta respuesta porque ignora la validez perfecta de la pregunta, es decir, que hay casos en los que realmente necesita saber el separador de ruta que se está utilizando. Por ejemplo, la necesidad de dividir una ruta en partes usaría el separador.
MirroredFate
2
@VVS: no funciona en escenarios en los que usa ambos tipos de barras (al menos en Windows 7). Considere el caso en el que está construyendo una variable usando __dirname y luego necesita agregar el resto de la ruta. Por ejemplo: __dirname + '/ images'. En ese ejemplo, __dirname usará las barras diagonales específicas del sistema operativo, pero si intentas usar / images y estás en Windows, terminarás con una ruta como c: \ somepath / images, y eso no funcionará en Windows. Me acabo de encontrar con este caso, por eso lo menciono :).
dcp
160

Use pathmodule in node.jsdevuelve el separador de archivos específico de la plataforma.
ejemplo

path.sep  // on *nix evaluates to a string equal to "/"

Editar: según el comentario de Sebas a continuación, para usar esto, debe agregar esto en la parte superior de su archivo js:

const path = require('path')
t98907
fuente
2
Se podría mejorar su respuesta que especifica cómo:path.sep .
Ionică Bizău
11
const path = require('path');
Sebas
Aunque sé que puedo usar '/' en la mayoría, si no en todos, de mis casos. Cuando imprimo la salida a la consola para recibir comentarios o registrarme. Me gusta usar las mismas barras en una ruta completa.
b01
Creo que arriba es la respuesta correcta y también la solución más simple. Como señaló Sebas para obtener acceso al módulo de ruta, debe hacer path = require ('ruta'). Si eres un programador de Nodo, incluso un novato, probablemente ya lo sepas.
Panu Logic
7

La respuesta correcta

Sí, todos los sistemas operativos aceptan CD ../ o CD .. \ o CD .. independientemente de cómo se pasen los separadores. Pero, ¿qué hay de leer un camino de regreso? ¿Cómo sabría si se dice, una ruta de 'ventanas', con ' 'y \permitido.

El obvio '¡Duh!' Pregunta

Qué sucede cuando depende, por ejemplo, del directorio de instalación %PROGRAM_FILES% (x86)\Notepad++. Tome el siguiente ejemplo.

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);
    }
}

¿¡Que pasó!?

targetDirse establece en una subcadena entre los índices 0y 0( indexOf('/')está -1en C:\Program Files\Notepad\Notepad++.exe), lo que da como resultado la cadena vacía.

La solución...

Esto incluye código de la siguiente publicación: ¿Cómo determino el sistema operativo actual con Node.js?

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

Detección de SO del lado del servidor.

// 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; }

Detección del sistema operativo en el lado del navegador

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;

Función auxiliar para obtener el separador

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

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

// modifying our getDir method from above...

Función auxiliar para obtener el directorio principal (multiplataforma)

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() debe ser lo suficientemente inteligente para saber cuál está buscando.

Puede ser incluso realmente hábil y verificar ambos si el usuario está ingresando una ruta a través de la línea de comando, etc.

// 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);

También puede usar el módulo 'ruta' y path.sep como se indicó anteriormente, si desea cargar un módulo para hacer esta simple tarea. Personalmente, creo que es suficiente con verificar la información del proceso que ya está disponible para usted.

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

¡Y eso es todo!

Descifrado
fuente
1
Me gusta que presentó la lógica para encontrar el separador a usar, dividiéndolo en trozos manejables. Así es como trabaja un profesional como ingeniero. +1 por eso. Además, teniendo en cuenta la antigüedad de la pregunta y la falta de una NodeJSetiqueta, ha respondido tanto para el servidor como para el cliente . Tu respuesta responde completa y realmente a la pregunta. Para el nodo, creo que el módulo de ruta está bien porque no afectará el rendimiento del código de bytes generado y no debería afectar la legibilidad (una sola declaración de importación). Sin embargo, eres la única respuesta del lado del cliente. Este debería ser el aceptado.
Rik
1

Como ya se respondió aquí, puede encontrar el separador de ruta específico del sistema operativo path.joinpara construir manualmente su ruta. Pero también puede dejar path.joinhacer el trabajo, que es mi solución preferida cuando se trata de construcciones de rutas:

Ejemplo:

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
Benny Neugebauer
fuente
-3

Solo use "/", funciona en todos los sistemas operativos que yo sepa.

Vincent McNabb
fuente
4
el OP preguntó cómo determine, no cuál es el operador que trabaja en todas partes :-)
Steel Brain
3
Funciona cuando tienes que analizar una ruta para extraer algo.
Chris Seufert