Skip to content

Commit 178379d

Browse files
thalesbrunoSEWeiTung
authored andcommitted
pt-br:5.8 file-system (#2310)
Section 5.8 file-system: 1. how-to-read-files-in-nodejs.md 2. how-to-search-files-and-directories-in-nodejs.md 3. how-to-store-local-config-data.md 4. how-to-use-the-path-module.md 5. how-to-write-files-in-nodejs.md 6. secutiry/introduction.md
1 parent ce04045 commit 178379d

File tree

6 files changed

+348
-0
lines changed

6 files changed

+348
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: Como eu leio arquivos no node.js?
3+
date: '2011-08-26T10:08:50.000Z'
4+
tags:
5+
- filesystem
6+
difficulty: 2
7+
layout: knowledge-post.hbs
8+
---
9+
10+
Ler o conteúdo de um arquivo na memória é uma tarefa muito comum na programação, e, como em muitas outras coisas, a API principal do Node.js fornece métodos para tornar isso trivial. Há uma variedade de métodos do sistema de arquivos, todos contidos no módulo `fs`. O modo mais fácil de ler todo o conteúdo de um arquivo é com `fs.readFile`, como segue:
11+
12+
fs = require('fs');
13+
fs.readFile(file, [encoding], [callback]);
14+
15+
// file = (string) caminho do arquivo a ser lido
16+
17+
`encoding` é um parâmetro opcional que especifica o tipo de codificação para ler o arquivo. As codificações possíveis são 'ascii', 'utf8' e 'base64'. Se nenhuma codificação for fornecida, o valor padrão é `null`.
18+
19+
`callback` é uma função que será chamada quando um arquivo tiver sido lido e o conteúdo estiver pronto - são passados dois argumentos, `err` e `data`. Se não houver erros, `err` será `null` e `data` conterá o conteúdo do arquivo; caso contrário `err` irá conter a mensagem de erro.
20+
21+
Então, se nós quisermos ler o arquivo `/etc/hosts` e imprimí-lo no stdout (como o `cat` no UNIX):
22+
23+
fs = require('fs')
24+
fs.readFile('/etc/hosts', 'utf8', function (err,data) {
25+
if (err) {
26+
return console.log(err);
27+
}
28+
console.log(data);
29+
});
30+
31+
O conteúdo do `/etc/hosts` deve estar visível para você agora, desde que você tenha permissão para ler o arquivo em primeiro lugar.
32+
33+
Vamos agora dar uma olhada em um exemplo do que acontece quando você tenta ler um arquivo inválido - o exemplo mais fácil é um arquivo que não existe.
34+
35+
fs = require('fs');
36+
fs.readFile('/doesnt/exist', 'utf8', function (err,data) {
37+
if (err) {
38+
return console.log(err);
39+
}
40+
console.log(data);
41+
});
42+
43+
Esta é a saída:
44+
45+
{ stack: [Getter/Setter],
46+
arguments: undefined,
47+
type: undefined,
48+
message: 'ENOENT, No such file or directory \'/doesnt/exist\'',
49+
errno: 2,
50+
code: 'ENOENT',
51+
path: '/doesnt/exist' }
52+
53+
Este é um [Error object](/what-is-the-error-object) básico do Node.js - muitas vezes pode ser útil logar diretamente `err.stack`, uma vez que ele contém uma stack trace para o local no código em que o objeto Error foi criado.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: Como eu procuro arquivos e diretórios?
3+
date: '2011-08-26T10:08:50.000Z'
4+
tags:
5+
- filesystem
6+
difficulty: 1
7+
layout: knowledge-post.hbs
8+
---
9+
10+
Suponha que você queira listar todos os arquivos no seu diretório atual. Uma abordagem é utilizar a [função](/how-do-i-read-files-in-node-js) builtin `fs.readdir`. Isto lhe retornará um array com todos os arquivos e diretórios do caminho especificado:
11+
12+
fs = require('fs');
13+
14+
fs.readdir(process.cwd(), function (err, files) {
15+
if (err) {
16+
console.log(err);
17+
return;
18+
}
19+
console.log(files);
20+
});
21+
22+
23+
Infelizmente, se você quiser fazer uma lista recursiva dos arquivos, então as coisas rapidamente ficarão muito mais complicadas. Para evitar toda essa complexidade assustadora, esta é uma das circunstâncias onde uma biblioteca feita por usuários pode salvar o dia. [Node-findit](https://github.com/substack/node-findit), pela SubStack, é um módulo auxiliar para facilitar a busca por arquivos. Ele tem interfaces para permitir você trabalhar com callbacks, eventos, ou simplesmente da velha forma síncrona (o que na maioria das vezes não é uma boa ideia).
24+
25+
Para instalar `node-findit`, simplesmente use npm:
26+
27+
npm install findit
28+
29+
Na mesma pasta, crie um arquivo chamado `example.js`, e então adicione este código. Execute-o com `node example.js`. Este exemplo usa o `node-findit` com a interface baseada em eventos.
30+
31+
//Isto instancia o localizador de arquivos
32+
var finder = require('findit').find(__dirname);
33+
34+
//Isto fica escutando por diretórios encontrados
35+
finder.on('directory', function (dir) {
36+
console.log('Directory: ' + dir + '/');
37+
});
38+
39+
//Isto fica escutando por arquivos encontrados
40+
finder.on('file', function (file) {
41+
console.log('File: ' + file);
42+
});
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: Como armazenar dados de configuração local
3+
date: '2011-08-26T10:08:50.000Z'
4+
tags:
5+
- conventions
6+
- filesystem
7+
difficulty: 1
8+
layout: knowledge-post.hbs
9+
---
10+
11+
12+
Armazenar os dados de configuração da sua aplicação Node.js é muito simples - cada objeto no JavaScript pode ser facilmente renderizado como [JSON](/what-is-json), que por sua vez é apenas dados em string que podem ser enviados ou salvos da maneira que você preferir. A forma mais simples de fazer isso envolve os métodos built-in `JSON.parse()` e `JSON.stringify()`.
13+
14+
Vamos dar uma olhada em um exemplo muito simples (e imaginário). Primeiro, para salvar alguns dados bem simples:
15+
16+
var fs = require('fs');
17+
18+
var myOptions = {
19+
name: 'Avian',
20+
dessert: 'cake'
21+
flavor: 'chocolate',
22+
beverage: 'coffee'
23+
};
24+
25+
var data = JSON.stringify(myOptions);
26+
27+
fs.writeFile('./config.json', data, function (err) {
28+
if (err) {
29+
console.log('There has been an error saving your configuration data.');
30+
console.log(err.message);
31+
return;
32+
}
33+
console.log('Configuration saved successfully.')
34+
});
35+
36+
É realmente simples - apenas `JSON.stringify()` e então salve-o do jeito que você quiser.
37+
38+
Agora, vamos carregar alguns dados de configuração:
39+
40+
var fs = require('fs');
41+
42+
var data = fs.readFileSync('./config.json'),
43+
myObj;
44+
45+
try {
46+
myObj = JSON.parse(data);
47+
console.dir(myObj);
48+
}
49+
catch (err) {
50+
console.log('There has been an error parsing your JSON.')
51+
console.log(err);
52+
}
53+
54+
NODE PRO TIP: Mesmo que você não goste de usar `try/catch`, este é um lugar para usá-lo. `JSON.parse` é um analisador JSON muito rígido, e erros são comuns - mais importante, contudo, `JSON.parse` usa a declaração `throw` em vez de dar uma callback, então `try/catch` é o único jeito de se proteger contra os erros.
55+
56+
Usar o método built-in `JSON` pode lhe levar longe, mas como tantos outros problemas que você pode estar procurando resolver com Node.js, já há uma solução da comunidade que pode levar você muito além. A solução, neste caso, é o `nconf`. Escrito por Charlie Robbins, é um gerenciador de configurações para Node.js que suporta armazenamento em memória, armazenamento de arquivos local, bem como suporte a backend `redis`, provido por um módulo separado.
57+
58+
Vamos dar uma olhada agora em como nós realizaríamos acessos a algumas configurações locais com o `nconf`. Primeiro, você precisará instalá-lo no diretório do projeto:
59+
60+
npm install nconf
61+
62+
Após isso, a sintaxe é moleza. Veja um exemplo:
63+
64+
var nconf = require('nconf');
65+
66+
nconf.use('file', { file: './config.json' });
67+
nconf.load();
68+
nconf.set('name', 'Avian');
69+
nconf.set('dessert:name', 'Ice Cream');
70+
nconf.set('dessert:flavor', 'chocolate');
71+
72+
console.log(nconf.get('dessert'));
73+
74+
nconf.save(function (err) {
75+
if (err) {
76+
console.error(err.message);
77+
return;
78+
}
79+
console.log('Configuration saved successfully.');
80+
});
81+
82+
A única coisa que requer atenção aqui é o delimitador - ':'. Quando se acessa propriedades aninhadas com o `nconf`, os dois-pontos são usados para delimitar os namespaces dos nomes das chaves. Se uma sub-chave específica não é fornecida, o objeto inteiro é definido ou retornado.
83+
84+
Quando usa-se o `nconf` para guardar seus dados de configurações em um arquivo, `nconf.save()` e `nconf.load()` são os únicos momentos em que acontecerá interações com o arquivo atual. Todos os outros acessos são realizados em uma cópia de seus dados em memória, que não serão persistidos sem uma chamada do `nconf.save()`. De maneira semelhante, se você está tentando trazer de volta dados de configuração da última vez que sua aplicação rodou, eles não existirão em memória sem uma chamada para `nconf.load()`, como mostrado acima.
85+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Como usar o módulo path?
3+
date: '2011-08-26T10:08:50.000Z'
4+
tags:
5+
- core
6+
- filesystem
7+
difficulty: 1
8+
layout: knowledge-post.hbs
9+
---
10+
11+
O módulo path contém muitas funções auxiliares para ajudar a tornar a manipulação de caminhos mais fácil.
12+
13+
A primeira função que vale a pena mencionar é `path.normalize`. Esta função pega um caminho (na forma de uma string) e remove barras duplicadas e normaliza abreviações de diretórios, como '.' para 'este diretório' e '..' para 'um diretório acima'. Por exemplo:
14+
15+
> var path = require('path');
16+
> path.normalize('/a/.///b/d/../c/')
17+
'/a/b/c/'
18+
19+
Uma função intimamente relacionada a `normalize` é `join`. Esta função recebe um número variável de argumentos, junta-os, e normaliza o caminho.
20+
21+
> var path = require('path');
22+
> path.join('/a/.', './//b/', 'd/../c/')
23+
'/a/b/c'
24+
25+
Um uso possível do `join` é para manipular caminhos quando servem urls:
26+
27+
> var path = require('path');
28+
> var url = '/index.html';
29+
> path.join(process.cwd(), 'static', url);
30+
'/home/nico/static/index.html'
31+
32+
Há três funções que são usadas para extrair as várias partes do nome de um caminho: `basename`, `extname`, e `dirname`.
33+
- `basename` retorna o último pedaço do caminho recebido.
34+
- `extname` retorna a extensão do último pedaço. Geralmente para diretórios, `extname` retorna apenas ''.
35+
- Finalmente, `dirname` retorna tudo que `basename` não retorna.
36+
Por exemplo:
37+
38+
> var path = require('path')
39+
> var a = '/a/b/c.html'
40+
> path.basename(a)
41+
'c.html'
42+
> path.extname(a)
43+
'.html'
44+
> path.dirname(a)
45+
'/a/b'
46+
47+
Note que `basename` tem um segundo parâmetro opcional que extrairá a extensão se você passa a extensão correta.
48+
49+
> var path = require('path')
50+
> var a = '/a/b/c.html'
51+
> path.basename(a, path.extname(a))
52+
'c'
53+
54+
Por último, o módulo `path` fornece métodos para checar se um determinado caminho existe ou não: `exists` e `existsSync` Os dois recebem o caminho de um arquivo como primeiro parâmetro.
55+
56+
`exists` recebe uma callback como seu segundo parâmetro, a qual é retornado um booleano representando a existência do arquivo.
57+
58+
`existsSync`, por outro lado, checa o caminho recebido de forma síncrona. No Node.js, você normalmente irá querer usar as funções assíncronas para entrada/saída no sistema de arquivos - as versões síncronas bloquearão todo o seu processo até que esteja finalizado.
59+
60+
Bloqueio nem sempre é uma coisa ruim. Checar a existência de um arquivo de configuração essencial de forma síncrona faz sentido, por exemplo - não interessa muito se seu processo está bloqueado por algo que ele não pode viver sem! Por outro lado, entretanto, em um servidor HTTP muito ativo, qualquer entrada/saída de arquivos por requisição **DEVE** ser assíncrona, senão você responderá as requisições uma por uma. Veja o artigo em [operações assíncronas](/how-to-write-asynchronous-code) para mais detalhes.
61+
62+
> var path = require('path')
63+
> path.exists('/etc', function(exists){console.log("Does the file exist?", exists)})
64+
> Does the file exist? true
65+
66+
> path.existsSync('/etc')
67+
true
68+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: Como eu escrevo arquivos no node.js?
3+
date: '2011-08-26T10:08:50.000Z'
4+
tags:
5+
- filesystem
6+
difficulty: 2
7+
layout: knowledge-post.hbs
8+
---
9+
10+
Escrever em um arquivo é outra das tarefas básicas da programação que um desenvolvedor normalmente precisa conhecer - por sorte, esta tarefa é muito simples no Node.js. Nós podemos usar o conveniente método `writeFile` do módulo `fs` da biblioteca padrão, que pode evitar todo tipo de problemas e economizar tempo.
11+
12+
fs = require('fs');
13+
fs.writeFile(filename, data, [encoding], [callback])
14+
15+
`file = (string)` caminho do arquivo a ser lido
16+
17+
`data = (string or buffer)` os dados que você quer escrever no arquivo
18+
19+
`encoding = (optional string)` a codificação de `data`. Codificações possíveis são 'ascii', 'utf8', e 'base64'. Se nenhuma codificação for passada, então a 'utf8' será assumida.
20+
21+
`callback = (optional function (err) {})` Se não houver erro, `err === null`, se houver, `err` conterá a mensagem de erro.
22+
23+
Então, se nós quisermos escrever "Hello World" em `helloworld.txt`:
24+
25+
fs = require('fs');
26+
fs.writeFile('helloworld.txt', 'Hello World!', function (err) {
27+
if (err) return console.log(err);
28+
console.log('Hello World > helloworld.txt');
29+
});
30+
31+
[conteúdo de helloworld.txt]:
32+
Hello World!
33+
34+
Se nós propositalmente quisermos causar um erro, podemos tentar escrever em um arquivo que nós não temos permissão de acesso:
35+
36+
fs = require('fs')
37+
fs.writeFile('/etc/doesntexist', 'abc', function (err,data) {
38+
if (err) {
39+
return console.log(err);
40+
}
41+
console.log(data);
42+
});
43+
44+
{ stack: [Getter/Setter],
45+
arguments: undefined,
46+
type: undefined,
47+
message: 'EACCES, Permission denied \'/etc/doesntexist\'',
48+
errno: 13,
49+
code: 'EACCES',
50+
path: '/etc/doesntexist' }
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: Como eu posso proteger meu código?
3+
date: null
4+
tags:
5+
- filesystem
6+
- security
7+
difficulty: 3
8+
layout: knowledge-post.hbs
9+
---
10+
11+
Às vezes, você pode querer deixar usuários lerem ou escreverem arquivos em seu servidor. Por exemplo, talvez você queira escrever um software de fórum sem usar um banco de dados de verdade. O problema é que você não quer que seus usuários possam modificar ou ler todo e qualquer arquivo em seu servidor, e por vezes há formas de contornar restrições que deveriam impedi-los. Continue lendo para ver como você pode proteger seu código contra atacantes malvados tentando bagunçar seus arquivos.
12+
13+
Poison Null Bytes
14+
=================
15+
Poison null bytes é um modo de enganar o seu código para que ele veja outro nome de arquivo em vez do que realmente está sendo aberto. Isto pode, em muitos casos, ser usado para contornar proteções a directory traversal, para enganar servidores a entregar arquivos com tipos errados e para contornar restrições nos nomes de arquivos que podem ser usados. [Aqui está uma descrição mais detalhada.](http://groups.google.com/group/nodejs/browse_thread/thread/51f66075e249d767/85f647474b564fde) Sempre use código como este quando estiver acessando arquivos com nomes fornecidos pelo usuário:
16+
17+
if (filename.indexOf('\0') !== -1) {
18+
return respond('That was evil.');
19+
}
20+
21+
Whitelisting
22+
============
23+
Você nem sempre será capaz de usar whitelisting, mas se for, é muito fácil de implementar e difícil de dar errado. Por exemplo, se você souber que todos os nomes de arquivos são strings alfanuméricas em caixa baixa:
24+
25+
if (!/^[a-z0-9]+$/.test(filename)) {
26+
return respond('illegal character');
27+
}
28+
29+
Contudo, note que whitelisting sozinha não será suficiente assim que você permitir pontos e barras - pessoas poderiam entrar com coisas como `../../etc/passwd` a fim de obter arquivos de fora da pasta permitida.
30+
31+
Prevenindo Directory Traversal
32+
==============================
33+
Directory traversal significa que um atacante tenta acessar arquivos fora do diretório que você quer permitir que ele acesse. Você pode prevenir isto usando o módulo "path" nativo do Node.js. **Não reimplementar as coisas no módulo path por conta própria** - por exemplo, quando alguém executa seu código em um servidor windows, não manipular barras invertidas como barras normais permitirá que atacantes façam directory traversal.
34+
35+
Este exemplo assume que você já checou a variável `userSuppliedFilename` como descrito na seção acima "Poison Null Bytes".
36+
37+
var rootDirectory = '/var/www/';
38+
39+
Garanta que você tem uma barra no final do nome dos diretórios permitidos - você não quer que pessoas sejam capazes de acessar `/var/www-secret/`, não é?.
40+
41+
var path = require('path');
42+
var filename = path.join(rootDirectory, userSuppliedFilename);
43+
44+
Agora `filename` contém um caminho absoluto e não contém mais sequências `..` - `path.join` cuida disso. Entretanto, pode ser algo como `/etc/passwd` agora, aí você tem que checar se começa com `rootDirectory`:
45+
46+
if (filename.indexOf(rootDirectory) !== 0) {
47+
return respond('trying to sneak out of the web root?');
48+
}
49+
50+
Agora a varável `filename` deve conter o nome do arquivo ou diretório que está dentro do diretório permitido (a menos que ele não exista).

0 commit comments

Comments
 (0)