Node.JS 폴더의 파일 루프
디렉터리에 있는 파일을 루프하여 찾아보려고 하지만 구현하는 데 문제가 있습니다.여러 개의 파일을 가져온 다음 다른 폴더로 이동하는 방법은 무엇입니까?
var dirname = 'C:/FolderwithFiles';
console.log("Going to get file info!");
fs.stat(dirname, function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("Got file info successfully!");
// Check file type
console.log("isFile ? " + stats.isFile());
console.log("isDirectory ? " + stats.isDirectory());
});
콜백이 있는 이전 응답
fs.readdir 함수를 사용하여 디렉토리 내용을 가져오고 fs.rename 함수를 사용하여 실제로 이름을 변경하려고 합니다.코드를 실행하기 전에 완료될 때까지 기다려야 하는 경우 두 기능 모두 동기화 버전이 있습니다.
저는 당신이 설명한 대로 빠른 스크립트를 작성했습니다.
var fs = require('fs');
var path = require('path');
// In newer Node.js versions where process is already global this isn't necessary.
var process = require("process");
var moveFrom = "/home/mike/dev/node/sonar/moveme";
var moveTo = "/home/mike/dev/node/sonar/tome"
// Loop through all the files in the temp directory
fs.readdir(moveFrom, function (err, files) {
if (err) {
console.error("Could not list the directory.", err);
process.exit(1);
}
files.forEach(function (file, index) {
// Make one pass and make the file complete
var fromPath = path.join(moveFrom, file);
var toPath = path.join(moveTo, file);
fs.stat(fromPath, function (error, stat) {
if (error) {
console.error("Error stating file.", error);
return;
}
if (stat.isFile())
console.log("'%s' is a file.", fromPath);
else if (stat.isDirectory())
console.log("'%s' is a directory.", fromPath);
fs.rename(fromPath, toPath, function (error) {
if (error) {
console.error("File moving error.", error);
} else {
console.log("Moved file '%s' to '%s'.", fromPath, toPath);
}
});
});
});
});
로컬 컴퓨터에서 테스트했습니다.
node testme.js
'/home/mike/dev/node/sonar/moveme/hello' is a file.
'/home/mike/dev/node/sonar/moveme/test' is a directory.
'/home/mike/dev/node/sonar/moveme/test2' is a directory.
'/home/mike/dev/node/sonar/moveme/test23' is a directory.
'/home/mike/dev/node/sonar/moveme/test234' is a directory.
Moved file '/home/mike/dev/node/sonar/moveme/hello' to '/home/mike/dev/node/sonar/tome/hello'.
Moved file '/home/mike/dev/node/sonar/moveme/test' to '/home/mike/dev/node/sonar/tome/test'.
Moved file '/home/mike/dev/node/sonar/moveme/test2' to '/home/mike/dev/node/sonar/tome/test2'.
Moved file '/home/mike/dev/node/sonar/moveme/test23' to '/home/mike/dev/node/sonar/tome/test23'.
Moved file '/home/mike/dev/node/sonar/moveme/test234' to '/home/mike/dev/node/sonar/tome/test234'.
업데이트: fs.sync/wait로 함수를 약속합니다.
ma11hew28의 답변(여기에 표시됨)에서 영감을 받아 위와 동일하지만 fs.promise의 비동기 함수를 사용합니다.ma11hew28에 의해 언급된 것처럼, 이것은 v12.12.0에 추가된 fs.promise.opendir에 대한 메모리 제한이 있을 수 있습니다.
아래의 빠른 코드.
//jshint esversion:8
//jshint node:true
const fs = require( 'fs' );
const path = require( 'path' );
const moveFrom = "/tmp/movefrom";
const moveTo = "/tmp/moveto";
// Make an async function that gets executed immediately
(async ()=>{
// Our starting point
try {
// Get the files as an array
const files = await fs.promises.readdir( moveFrom );
// Loop them all with the new for...of
for( const file of files ) {
// Get the full paths
const fromPath = path.join( moveFrom, file );
const toPath = path.join( moveTo, file );
// Stat the file to see if we have a file or dir
const stat = await fs.promises.stat( fromPath );
if( stat.isFile() )
console.log( "'%s' is a file.", fromPath );
else if( stat.isDirectory() )
console.log( "'%s' is a directory.", fromPath );
// Now move async
await fs.promises.rename( fromPath, toPath );
// Log because we're crazy
console.log( "Moved '%s'->'%s'", fromPath, toPath );
} // End for...of
}
catch( e ) {
// Catch anything bad that happens
console.error( "We've thrown! Whoops!", e );
}
})(); // Wrap in parenthesis and call now
fs.readdir(path[, options], callback)
(마이키 A)Leonetti)와 그 변형(fsPromises.readdir(path[, options])
및 )은 각각 디렉토리의 모든 항목을 한 번에 메모리로 읽습니다.대부분의 경우에 유용하지만 디렉토리에 항목이 매우 많거나 응용프로그램의 메모리 설치 공간을 줄이려는 경우에는 한 번에 하나씩 디렉토리의 항목을 반복할 수 있습니다.
비동기식으로
디렉터리는 비동기식이므로 다음과 같은 작업을 수행할 수 있습니다.
const fs = require('fs')
async function ls(path) {
const dir = await fs.promises.opendir(path)
for await (const dirent of dir) {
console.log(dirent.name)
}
}
ls('.').catch(console.error)
또는 및/또는 직접 사용할 수 있습니다.
동시에
디렉터리는 동기화할 수 없지만 직접 사용할 수 있습니다.예:
const fs = require('fs')
const dir = fs.opendirSync('.')
let dirent
while ((dirent = dir.readSync()) !== null) {
console.log(dirent.name)
}
dir.closeSync()
또는 디렉터리를 동기화할 수 있습니다.예:
const fs = require('fs')
function makeDirectoriesSyncIterable() {
const p = fs.Dir.prototype
if (p.hasOwnProperty(Symbol.iterator)) { return }
const entriesSync = function* () {
try {
let dirent
while ((dirent = this.readSync()) !== null) { yield dirent }
} finally { this.closeSync() }
}
if (!p.hasOwnProperty(entriesSync)) { p.entriesSync = entriesSync }
Object.defineProperty(p, Symbol.iterator, {
configurable: true,
enumerable: false,
value: entriesSync,
writable: true
})
}
makeDirectoriesSyncIterable()
그런 다음 다음 다음과 같은 작업을 수행할 수 있습니다.
const dir = fs.opendirSync('.')
for (const dirent of dir) {
console.log(dirent.name)
}
참고: "사용 중인 프로세스에서는 이러한 호출의 비동기 버전을 사용합니다.동기화된 버전은 완료될 때까지 전체 프로세스를 차단하여 모든 연결을 중지합니다."
참조:
- Node.js 설명서:파일 시스템:
Class fs.Dir
- Node.js 소스 코드:
fs.Dir
- GitHub: nodejs/node:문제: 스트리밍 / 반복 fs.readdir #583
디렉토리의 모든 폴더 읽기
const readAllFolder = (dirMain) => {
const readDirMain = fs.readdirSync(dirMain);
console.log(dirMain);
console.log(readDirMain);
readDirMain.forEach((dirNext) => {
console.log(dirNext, fs.lstatSync(dirMain + "/" + dirNext).isDirectory());
if (fs.lstatSync(dirMain + "/" + dirNext).isDirectory()) {
readAllFolder(dirMain + "/" + dirNext);
}
});
};
제공된 답변은 단일 폴더에 대한 것입니다.다음은 모든 폴더가 동시에 처리되지만 작은 폴더나 파일이 먼저 완료되는 여러 폴더에 대한 비동기 구현입니다.
피드백이 있으면 댓글을 달아주세요.
비동기식으로 여러 폴더
const fs = require('fs')
const util = require('util')
const path = require('path')
// Multiple folders list
const in_dir_list = [
'Folder 1 Large',
'Folder 2 Small', // small folder and files will complete first
'Folder 3 Extra Large'
]
// BEST PRACTICES: (1) Faster folder list For loop has to be outside async_capture_callback functions for async to make sense
// (2) Slower Read Write or I/O processes best be contained in an async_capture_callback functions because these processes are slower than for loop events and faster completed items get callback-ed out first
for (i = 0; i < in_dir_list.length; i++) {
var in_dir = in_dir_list[i]
// function is created (see below) so each folder is processed asynchronously for readFile_async that follows
readdir_async_capture(in_dir, function(files_path) {
console.log("Processing folders asynchronously ...")
for (j = 0; j < files_path.length; j++) {
file_path = files_path[j]
file = file_path.substr(file_path.lastIndexOf("/") + 1, file_path.length)
// function is created (see below) so all files are read simultaneously but the smallest file will be completed first and get callback-ed first
readFile_async_capture(file_path, file, function(file_string) {
try {
console.log(file_path)
console.log(file_string)
} catch (error) {
console.log(error)
console.log("System exiting first to catch error if not async will continue...")
process.exit()
}
})
}
})
}
// fs.readdir async_capture function to deal with asynchronous code above
function readdir_async_capture(in_dir, callback) {
fs.readdir(in_dir, function(error, files) {
if (error) { return console.log(error) }
files_path = files.map(function(x) { return path.join(in_dir, x) })
callback(files_path)
})
}
// fs.readFile async_capture function to deal with asynchronous code above
function readFile_async_capture(file_path, file, callback) {
fs.readFile(file_path, function(error, data) {
if (error) { return console.log(error) }
file_string = data.toString()
callback(file_string)
})
}
언급URL : https://stackoverflow.com/questions/32511789/looping-through-files-in-a-folder-node-js
'programing' 카테고리의 다른 글
파워셸에서 우아하게 멈춘다. (0) | 2023.08.12 |
---|---|
Android에서 EditText의 문자를 제한하려면 InputFilter를 어떻게 사용합니까? (0) | 2023.08.12 |
Python에서 하위 프로세스, 멀티프로세싱 및 스레드 중에서 결정하시겠습니까? (0) | 2023.08.12 |
텍스트 보기 텍스트를 클릭하거나 탭하는 방법 (0) | 2023.08.12 |
MySQL 테이블에 사용자 정의 CHECK 제약 조건을 추가하려면 어떻게 해야 합니까? (0) | 2023.08.12 |