[英]How to download files in /tmp folder of Google Cloud Function and then upload it in Google Cloud Storage
所以我需要部署一個谷歌雲 Function 允許我做兩件事。
第一個是在雲 Function 的 /tmp 本地目錄上的 SFTP/FTP 服務器上下載任何文件。 然后,第二步是將這個文件上傳到 Google Cloud Storage 的存儲桶中。
實際上我知道如何上傳,但我不知道如何從 ftp 服務器下載文件到我的本地 /tmp 目錄。
所以,實際上我已經編寫了一個 GCF,它接收參數(在主體上)、配置(config)以允許我在 FTP 服務器上連接、文件名和路徑。
對於我的測試,我使用了以下 ftp 服務器測試: https://www.sftp.net/public-online-sftp-servers與此配置。
{
config:
{
hostname: 'test.rebex.net',
username: 'demo',
port: 22,
password: 'password'
},
filename: 'FtpDownloader.png',
path: '/pub/example'
}
下載后,我開始上傳。 為此,我檢查是否在 UPLOAD 之前在 '/tmp/filename' 中找到了 DOWNLOAD 文件,但這里的文件比較緊張。
請參閱以下代碼:
exports.transferSFTP = (req, res) =>
{
let body = req.body;
if(body.config)
{
if(body.filename)
{
//DOWNLOAD
const Client = require('ssh2-sftp-client');
const fs = require('fs');
const client = new Client();
let remotePath
if(body.path)
remotePath = body.path + "/" + body.filename;
else
remotePath = "/" + body.filename;
let dst = fs.createWriteStream('/tmp/' + body.filename);
client.connect(body.config)
.then(() => {
console.log("Client is connected !");
return client.get(remotePath, dst);
})
.catch(err =>
{
res.status(500);
res.send(err.message);
})
.finally(() => client.end());
//UPLOAD
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({projectId: 'my-project-id'});
const bucket = storage.bucket('my-bucket-name');
const file = bucket.file(body.filename);
fs.stat('/tmp/' + body.filename,(err, stats) =>
{
if(stats.isDirectory())
{
fs.createReadStream('/tmp/' + body.filename)
.pipe(file.createWriteStream())
.on('error', (err) => console.error(err))
.on('finish', () => console.log('The file upload is completed !!!'));
console.log("File exist in tmp directory");
res.status(200).send('Successfully executed !!!')
}
else
{
console.log("File is not on the tmp Google directory");
res.status(500).send('File is not loaded in tmp Google directory')
}
});
}
else res.status(500).send('Error: no filename on the body (filename)');
}
else res.status(500).send('Error: no configuration elements on the body (config)');
}
因此,我收到以下消息:“文件未加載到 tmp Google 目錄中”,因為在 fs.stat() 方法之后,stats.isDirectory() 為 false。 在我使用 fs.stats() 方法檢查文件是否在這里之前,我剛剛編寫了具有相同文件名但沒有內容的文件。 因此,我得出的結論是,我的上傳工作,但沒有 DONWLOAD 文件,很難將其復制到 Google 雲存儲中。
感謝您的時間,我希望我能找到解決方案。
問題是在執行上傳的代碼開始運行之前,您沒有等待下載完成。 雖然您確實有一個 catch() 語句,但這還不夠。
將第一部分(下載)視為單獨的代碼塊。 您已經告訴 Javascript 到 go 異步執行該塊。 一旦您的腳本完成此操作,它就會立即繼續執行您的腳本的 rest。 它不會等待“塊”完成。 因此,您的上傳代碼在下載完成之前運行。
你可以做兩件事。 第一個是將執行上傳的所有代碼移動到 get() 調用之后的“then”塊中(順便說一句,您可以使用 fastGet() 來簡化事情)。 例如
client.connect(body.config)
.then(() => {
console.log("Client is connected !");
return client.fastGet(remotePath, localPath);
})
.then(() => {
// do the upload
})
.catch(err => {
res.status(500);
res.send(err.message);
})
.finally(() => client.end());
另一種選擇是使用 async/await,這將使您的代碼看起來更“同步”。 類似於(未經測試)的東西
async function doTransfer(remotePath, localPath) {
try {
let client - new Client();
await client.connect(config);
await client.fastGet(remotePath, localPath);
await client.end();
uploadFile(localPath);
} catch(err) {
....
}
}
這是一個 github 項目,它回答了與您類似的問題。
在這里,他們部署了一個 Cloud Function 從 FTP 下載文件並將它們直接上傳到存儲桶,跳過了獲取臨時文件的步驟。
該代碼有效,此 github 中的部署方式未更新,因此我將按照我的建議放置部署步驟並驗證它們是否有效:
激活 Cloud Shell 並運行:
從 github 克隆存儲庫: git clone https://github.com/RealKinetic/ftp-bucket.git
切換到目錄: cd ftp-bucket
根據需要調整您的代碼
創建一個 GCS 存儲桶,如果您還沒有,可以通過gsutil mb -p [PROJECT_ID] gs://[BUCKET_NAME]
創建一個
部署: gcloud functions deploy importFTP --stage-bucket [BUCKET_NAME] --trigger-http --runtime nodejs8
以我個人的經驗,這比在兩個功能中使用它更有效,除非您需要在同一雲 function 中進行一些文件編輯
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.