it-swarm-pt.tech

Node.js verifica se o caminho é um arquivo ou diretório

Não consigo obter nenhum resultado de pesquisa que explique como fazer isso.

Tudo o que eu quero fazer é saber se um determinado caminho é um arquivo ou um diretório (pasta).

320
ThomasReggi

fs.lstatSync(path_string).isDirectory() deveria dizer-lhe. Do docs :

Objetos retornados de fs.stat () e fs.lstat () são desse tipo.

stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (only valid with fs.lstat())
stats.isFIFO()
stats.isSocket()

NOTA: A solução acima irá throw um Error if; por ex, o file ou directory não existe. Se você quer um truthy ou falsy tente fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory(); como mencionado por Joseph nos comentários abaixo.

500
Jason Sperske

Atualização: Node.Js> = 10

Podemos usar a nova API --- fs.promises

Experimental Este recurso ainda está em desenvolvimento ativo e sujeito a alterações não compatíveis com versões anteriores, ou até mesmo remoção, em qualquer versão futura. O uso do recurso não é recomendado em ambientes de produção. Os recursos experimentais não estão sujeitos ao modelo de versão semântica do Node.js.

const fs = require('fs').promises;

(async() => {

        try {
            const stat = await fs.lstat('test.txt');
            console.log(stat.isFile());
        } catch(err) {
            console.error(err);
        }
})();

Qualquer versão do Node.Js

Veja como você detectaria se um caminho é um arquivo ou um diretório de forma assíncrona , que é a abordagem recomendada no nó. usando fs.lstat

const fs = require("fs");

let path = "/path/to/something";

fs.lstat(path, (err, stats) => {

    if(err)
        return console.log(err); //Handle error

    console.log(`Is file: ${stats.isFile()}`);
    console.log(`Is directory: ${stats.isDirectory()}`);
    console.log(`Is symbolic link: ${stats.isSymbolicLink()}`);
    console.log(`Is FIFO: ${stats.isFIFO()}`);
    console.log(`Is socket: ${stats.isSocket()}`);
    console.log(`Is character device: ${stats.isCharacterDevice()}`);
    console.log(`Is block device: ${stats.isBlockDevice()}`);
});

Observe ao usar a API síncrona:

Ao usar o formulário síncrono, quaisquer exceções são lançadas imediatamente. Você pode usar o comando try/catch para manipular exceções ou permitir que elas aumentem.

try{
     fs.lstatSync("/some/path").isDirectory()
}catch(e){
   // Handle error
   if(e.code == 'ENOENT'){
     //no such file or directory
     //do something
   }else {
     //do something else
   }
}
41
Marcos Casagrande

Sério, pergunta existe há cinco anos e não há fachada de Nice?

function is_dir(path) {
    try {
        var stat = fs.lstatSync(path);
        return stat.isDirectory();
    } catch (e) {
        // lstatSync throws an error if path doesn't exist
        return false;
    }
}
11
lama12345

Dependendo de suas necessidades, você provavelmente pode confiar no módulo path do nó.

Você pode não conseguir acertar o sistema de arquivos (por exemplo, o arquivo ainda não foi criado) e você provavelmente evitará o acesso ao sistema de arquivos, a menos que você realmente precise da validação extra. Se você puder supor que o que está verificando segue o formato .<extname>, basta olhar o nome.

Obviamente, se você estiver procurando por um arquivo sem um extname, precisará acertar o sistema de arquivos para ter certeza. Mas mantenha-o simples até precisar de mais complicado.

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}
6
cndw

As respostas acima verificam se um sistema de arquivos contém um caminho que é um arquivo ou diretório. Mas não identifica se um determinado caminho é um arquivo ou diretório.

A resposta é identificar caminhos baseados em diretório usando "/". como -> "/ c/dos/run /." <- período de fuga.

Como um caminho de um diretório ou arquivo que ainda não foi escrito. Ou um caminho de um computador diferente. Ou um caminho onde existe um arquivo e um diretório com o mesmo nome.

// /tmp/
// |- dozen.path
// |- dozen.path/.
//    |- eggs.txt
//
// "/tmp/dozen.path" !== "/tmp/dozen.path/"
//
// Very few fs allow this. But still. Don't trust the filesystem alone!

// Converts the non-standard "path-ends-in-slash" to the standard "path-is-identified-by current "." or previous ".." directory symbol.
function tryGetPath(pathItem) {
    const isPosix = pathItem.includes("/");
    if ((isPosix && pathItem.endsWith("/")) ||
        (!isPosix && pathItem.endsWith("\\"))) {
        pathItem = pathItem + ".";
    }
    return pathItem;
}
// If a path ends with a current directory identifier, it is a path! /c/dos/run/. and c:\dos\run\.
function isDirectory(pathItem) {
    const isPosix = pathItem.includes("/");
    if (pathItem === "." || pathItem ==- "..") {
        pathItem = (isPosix ? "./" : ".\\") + pathItem;
    }
    return (isPosix ? pathItem.endsWith("/.") || pathItem.endsWith("/..") : pathItem.endsWith("\\.") || pathItem.endsWith("\\.."));
} 
// If a path is not a directory, and it isn't empty, it must be a file
function isFile(pathItem) {
    if (pathItem === "") {
        return false;
    }
    return !isDirectory(pathItem);
}

Versão do nó: v11.10.0 - fev 2019

Último pensamento: Por que até mesmo atingiu o sistema de arquivos?

1
TamusJRoyce

Aqui está uma função autônoma que eu uso em alguns dos meus programas. Ninguém está usando os recursos promisify e await/async neste post, então pensei em compartilhar.

const isDirectory = async path => {
  try {
    return (await require('util').promisify(require('fs').lstat)(path)).isDirectory()
  } catch (e) {
    return false // or custom the error
  }
}

Nota: Eu não uso require('fs').promises; porque ele é experimental há um ano, e não depende dele.

0
vdegenne