MATLAB でWeb サーバーにファイルをアップロードしたい
今回は約1ヶ月ぶりにMATLAB ネタを書きます。以前の記事では緯度経度の位置情報のデータからある領域の内外に入っているかどうか判定する方法について書きましたが、今回はガラッと変わってWeb サーバーへのクライアントの機能。ずばり、Web サーバーにファイルをアップロードする方法についてです。
書こうと思ったきっかけは、全然情報が無くて苦労したからです。公式ドキュメントやMATLAB Answers の回答が充実しているMATLAB ですが、Web サーバーにファイルをアップロードする方法についてはドキュメントに無かったり、Answers でも質問が放置されたままになっている状態。
webwrite だと苦しいのでmatlab.net.http の出番です
MATLAB にはHTTP GET を簡単におこなえるwebread と、HTTP POSTのクライアント機能を有するwebwrite があり、ファイルアップロードもこのwebwrite で行けるだろうとあれこれ試しました。weboptions でリクエスト手法をapplication/x-www-form-urlencoded などに変更しても、webwrite で実行するときにはJSON 形式でないと受け付けないと出てしまい、webwrite は簡易的に使える反面小回りが利かなくて、カスタムのWeb サーバーにファイルを送るには不向きでした。
そこでR2016b から導入されたmatlab.net.http という「MATLAB HTTP インターフェイス」の出番です。ここにFileProvider というファイルをアップロードするためのクラスがmatlab.net.http.io の中にR2018a で導入されていますので、それを使わない手はありません。
このFileProvider を使ってファイルプロバイダーを作り、それを同じくR2018a から導入されたMultipartFormProvider を使ってマルチパートのフォームデータとしてWeb サーバーに送ればOK です。
MATLAB のサンプルコードは以下のとおりです。
fp = matlab.net.http.io.FileProvider('filename.ext');
provider = matlab.net.http.io.MultipartFormProvider("files", fp);
netHttpRequest = matlab.net.http.RequestMessage('post', [], provider);
response = netHttpRequest.send(url);
Code language: Matlab (matlab)
ここで長々しくmatlab.net.http.io.FileProvider とクラス名をフルで指定していますが、import をしておけば短縮することもできます。
import matlab.net.http.*
import matlab.net.http.io.*;
fp = FileProvider('filename.ext');
provider = MultipartFormProvider("files", fp);
netHttpRequest = RequestMessage('post', [], provider);
response = netHttpRequest.send(url);
Code language: Matlab (matlab)
Node.js のWeb サーバーにアップロードしてみる
それでは実際にWeb サーバーにファイルをアップロードしてみましょう。
Web サーバーとして今回テストに使用するのはNode.js 。普段私はExpress というフレームワークを使ってNode.js のWeb サーバーを作ることが多いですが、ここではExpress は使わずに最小限のモジュールだけで実装します。W3Schools のサンプルを参考にしてカスタマイズしました。
Node.js にはformidable というフォームデータをパースする便利なモジュールがあるので、これを事前にnpm でインストールしておきます。
npm install formidable --save
Code language: DOS .bat (dos)
app.js
const fs = require('fs');
const http = require('http');
const path = require('path');
const formidable = require('formidable');
http.createServer(function (req, res) {
if (req.url === '/upload') {
// 入力フォームデータの作成
let form = new formidable.IncomingForm();
// アップロード先をuploadsフォルダーに変更
form.uploaddir = path.join(__dirname, '/uploads');
// フォームデータをパース
form.parse(req, function (err, fields, files) {
let file = files.files;
// ファイル名を「9e0da8800f5f6424e3776f900」のような名前からリネーム
fs.renameSync(file.filepath, path.join(form.uploaddir, file.originalFilename));
res.write('File uploaded');
res.end();
});
}
}).listen(3000);
Code language: JavaScript (javascript)
ファイルがアップロードされるとファイル名が「9e0da8800f5f6424e3776f900」のような拡張子の無いランダムな文字列になってしまい、かつ一時フォルダー (Windows だとAppData の中)にファイルが格納されてしまうので、18行目でフォルダーをapp.js がある現在のフォルダー内のuploads サブフォルダーに、ファイル名がオリジナルのファイル名になるようにリネームする処理を入れています。
それではこのWeb サーバーにMATLAB からファイルをアップロードしてみましょう。試しに、ドキュメントの例で使用されるpeppers.png というファイルを上げてみます。
url = "http://localhost:3000/upload";
filenameToUpload = 'peppers.png';
provider = matlab.net.http.io.MultipartFormProvider("files", matlab.net.http.io.FileProvider(filenameToUpload));
netHttpRequest = matlab.net.http.RequestMessage('post', [], provider);
response = netHttpRequest.send(url);
if response.StatusCode == 200
disp('Success')
end
Code language: Matlab (matlab)
実行結果は
上記のコードを実行するとMATLAB のコマンドウィンドウには「Success」が表示され、Web サーバー側にはちゃんとuploads フォルダーにpeppers.png の画像が格納されました。
FileProvider とMutipartFormProvider を使ってMATLAB からWebサーバーへのファイルアップロードが無事にできましたね。
ではでは今日はこの辺で。
No responses yet