fs.readdir не читает файлы, извлеченные в локальный каталог (функция даже не работает) - PullRequest
0 голосов
/ 04 марта 2020

Я извлек zip-файлы в локальный каталог в моей лямбда-функции, однако функция fs.readdir не работает и также не возвращает ошибку. Я думаю, возможно, у меня есть синтаксическая ошибка при настройке функции для асинхронного запуска.

    // Make Directories for Zipped and Unzipped files
    try {
        const zipDirFolder = await mkdirp(localZippedFolder, { recursive: true });

        const unZipDirFolder = await mkdirp(localUnzippedFolder, { recursive: true });
        console.log(unZipDirFolder);

    // Download files from s3 Bucket
        let newFolder = await s3.getObject(params).promise()
        .then(data => {
            console.log(data);
            return data;
        });
        const newZipFile = newFolder.Body; 

    // Extract files from zipped folder and store them in a local directory
        let filezFolder = await fs.createReadStream(params.Key)
        .pipe(unzipper.Extract({path: unZipDirFolder}));
        console.log(unZipDirFolder);

    // Read Contents of that local directory    
        await fs.readdir(unZipDirFolder, function (err, files) {
            if (err) {
                console.log('THERE WAS AN ERROR:' + err);
            } else {
                console.log(files);
            }
        });
}

Проблема: fs.readdir не работает и не возвращает сообщение об ошибке.

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

В этом утверждении есть проблема:

let filezFolder = await fs.createReadStream(params.Key)
    .pipe(unzipper.Extract({path: unZipDirFolder}));

fs.createReadStream().pipe() не возвращает обещание. Таким образом, использование await на нем ничего полезного не дает. Итак, вы не дождались, пока .pipe() не закончится. Таким образом, вы звоните fs.readdir() до того, как будет выполнена операция распаковки.

В данный момент потоки не особенно благоприятны для обещаний. Возможно, вам потребуется зарегистрироваться для какого-либо события в результирующем потоке, который указывает, когда будет выполнена операция распаковки, а затем выполнить fs.readdir() из этого обработчика события. Я сам не знаю вашу библиотеку для распаковки, чтобы знать, какое событие или как лучше контролировать его на предмет завершения.

Поскольку .pipe() возвращает поток с возможностью записи, вы, вероятно, можете сделать это:

fs.createReadStream(params.Key)
    .pipe(unzipper.Extract({path: unZipDirFolder}))
    .on('finish', () => {
         fs.readdir(...)
    }).on('error', (err) => {
         // error handling here
         console.log(err);
    });

Вот простая маленькая отдельная программа, которая показывает концепцию, о которой я говорю:

const unzipper = require('unzipper');
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');

const inputZip = path.join(__dirname, "zip", "photos.zip");
const outputZipDir = path.join(__dirname, "zip-output")

function run() {
    fs.createReadStream(inputZip)
        .pipe(unzipper.Extract({ path: outputZipDir }))
        .on('finish', async () => {
            let files = await fsp.readdir(outputZipDir);
            console.log(files);
            // use the files here
        }).on('err', err => {
            console.log(err);
    });
}

run();

Настройка для этой программы - поместить photos.zip в подкаталог zip из где эта программа запускается и для создания подкаталога zip-output, из которого эта программа запускается для распакованных файлов, до go.


И вот многообещающая версия, которая использует ту же настройку:

const unzipper = require('unzipper');
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');

const inputZip = path.join(__dirname, "zip", "photos.zip");
const outputZipDir = path.join(__dirname, "zip-output")

// returns a promise that resolves/rejects when the unzip operation is done
function unzip(inputZip, outputDir) {
    return new Promise((resolve, reject) => {
        fs.createReadStream(inputZip)
            .pipe(unzipper.Extract({ path: outputDir }))
            .on('finish', resolve)
            .on('err', reject);

    });
}

async function run2() {
    await unzip(inputZip, outputZipDir);
    let files = await fsp.readdir(outputZipDir);
    console.log(files);
}

run2().catch(err => {
    console.log(err);
});
0 голосов
/ 04 марта 2020

Вероятно, это потому, что вы пытаетесь await fs.readdir и в то же время пытаетесь сделать обратный вызов. Вы не должны делать оба. Попробуйте удалить ожидание или настроить лямбда-функцию async и удалить обратный вызов.

//Using await (Don't forget to place this in a async function)
const res = await fs.readdir(yourFilePath);

//Using Callbacks
fs.readdir(yourFilePath, (err, files) => {
  if (err) {
      console.log('THERE WAS AN ERROR:' + err);
  } else {
      console.log(files);
  }
});

Или вы можете использовать fs.readdirSync и сделать

const res = fs.readdirSync(yourFilePath)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...