go言語でflagを使用したパラメータ指定を行う
とにかく実装
sample1.go
package main import ( "log" "flag" "os" ) // 引数取得エリア type ParamItem struct { Url string Count int User string Pass string } // 引数を指定して値を受け取る処理 func main() { // 処理開始 log.Println("start") param := new(ParamItem) // flagObj := flag.NewFlagSet(os.Args[0], flag.ExitOnError) // 引数を登録 flagObj.StringVar(¶m.Url, "url", "", "URLを設定してください。") flagObj.StringVar(¶m.User, "user", "", "ユーザ名を設定してください。") flagObj.StringVar(¶m.Pass, "pass", "", "パスワードを設定してください。") // パース処理 flagObj.Parse(os.Args[1:]) for 0 < flagObj.NArg() { flagObj.Parse(flagObj.Args()[1:]) } log.Println("url = " + param.Url) log.Println("user = " + param.User) log.Println("pass = " + param.Pass) // 処理終了 log.Println("end") }
↓
$ go run sample1.go -url http://hogehoge.com -user aaa -pass 1234 2017/10/28 17:29:07 start 2017/10/28 17:29:07 url = http://hogehoge.com 2017/10/28 17:29:07 user = aaa 2017/10/28 17:29:07 pass = 1234 2017/10/28 17:29:07 end $
ヘルプコマンドの場合
$ go run sample1.go -help 2017/10/28 17:29:46 start -pass string パスワードを設定してください。 -url string URLを設定してください。 -user string ユーザ名を設定してください。 exit status 2 $
順番ってキー名の昇順?
所感
項目名と連動するので引数で何が必要かなどの指定を用意しやすい。
設定ファイルでの読み込みと合わせて行えば役に立ちそう
go言語で設定ファイルを読み込み2(別パッケージにして扱う)
1つのファイルの場合
はメンテしづらいので分割する
ファイル構成
. ├── config │ └── appconfig.go ├── config.json └── sample2.go
こんな感じ
実装
config.json
{ "url": "http://hogehoge.com", "count": 100, "user": "hoge", "pass": "foo" }
config/appconfig.go
package config import ( "io/ioutil" "encoding/json" ) // 構造体定義 type Config struct { Url string `json:"url"` Count int `json:"count"` User string `json:"user"` Pass string `json:"pass"` } // configファイルを読み込み構造体へ割当 func Read(filename string) (*Config, error) { // 構造体を定義 c := new(Config) // 設定ファイルを読み込む jsonString, err := ioutil.ReadFile(filename) if err != nil { // エラー return c, err } // 設定 err = json.Unmarshal(jsonString, c) if err != nil { // エラー return c, err } // 正常 return c, nil }
sample2.go
package main import ( "log" "os" "strconv" "./config" ) // jsonの設定ファイルを読み込むサンプル func main() { // 処理開始 log.Println("start") // 構造体へconfigの結果を設定 c, err := config.Read("config.json") if err != nil { log.Println(err) os.Exit(1) } // 結果出力 log.Println("url = " + c.Url) log.Println("count = " + strconv.Itoa(c.Count)) log.Println("user = " + c.User) log.Println("pass = " + c.Pass) // 処理終了 log.Println("end") }
所感
うん、まあそれなりにスッキリした感じです。
構造体の場合は値渡しか参照渡しとなるかをきちんと考える必要がある
go言語でjson形式の設定ファイルを読み込む
実行する際の変数の外出
設定ファイルにして配置しておくとやりやすいので対応する。
前提
設定ファイルはjson
実装
config.json
{ "url": "http://hogehoge.com", "count": 100, "user": "hoge", "pass": "foo" }
sample1.go
package main import ( "log" "os" "io/ioutil" "encoding/json" "strconv" ) // jsonの設定ファイルを読み込むサンプル func main() { // 処理開始 log.Println("start") jsonString, err := ioutil.ReadFile("config.json") if err != nil { log.Println(err) os.Exit(1) } // config.jsonの中身を出力 // そのままだとbyteデータになるのでstringに変換 log.Println(string(jsonString)) // 構造体定義 type Config struct { Url string `json:"url"` Count int `json:"count"` User string `json:"user"` Pass string `json:"pass"` } // 設定変数用意 c := new(Config) // 設定 err = json.Unmarshal(jsonString, c) if err != nil { log.Println(err) os.Exit(2) } // 結果出力 log.Println("url = " + c.Url) log.Println("count = " + strconv.Itoa(c.Count)) log.Println("user = " + c.User) log.Println("pass = " + c.Pass) // 処理終了 log.Println("end") }
↓
$ go run sample1.go 2017/10/28 14:32:33 start 2017/10/28 14:32:33 { "url": "http://hogehoge.com", "count": 100, "user": "hoge", "pass": "foo" } 2017/10/28 14:32:33 url = http://hogehoge.com 2017/10/28 14:32:33 count = 100 2017/10/28 14:32:33 user = hoge 2017/10/28 14:32:33 pass = foo 2017/10/28 14:32:33 end $
注意点
構造体に設定する際はフィールドの項目は外部公開できるように1文字目を大文字にしておくこと
そうしないと構造体のデータに設定されてくれない
【C++】動的にデータを追加するvector、listを使う
実装
サンプル
//============================================================================ // Name : sample04.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <vector> #include <list> #include <cstring> using namespace std; int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! /** * vectorの場合 */ vector<string> strlist; strlist.push_back("aaaa1"); strlist.push_back("aaaa2"); strlist.push_back("aaaa3"); strlist.push_back("aaaa4"); // イテレータを使用して抽出 for (vector<string>::iterator it = strlist.begin(); it != strlist.end(); ++it) { cout << *it << endl; } vector<int> intlist; intlist.push_back(100); intlist.push_back(200); intlist.push_back(300); intlist.push_back(400); // 回数指定で抽出 for (int i=0;i<intlist.size();i++) { int a = intlist.operator[](i); cout << a << endl; } /** * listの場合 */ list<string> strlist2; strlist2.push_back("bbbb1"); strlist2.push_back("bbbb2"); strlist2.push_back("bbbb3"); strlist2.push_back("bbbb4"); // イテレータを使用して抽出 for (list<string>::iterator it = strlist2.begin(); it != strlist2.end(); ++it) { cout << *it << endl; } return 0; }
↓
!!!Hello World!!! aaaa1 aaaa2 aaaa3 aaaa4 100 200 300 400 bbbb1 bbbb2 bbbb3 bbbb4
vectorの場合
要素の途中の項目にもアクセスできます。listよりは少し遅いとのこと
listの場合
イテレータなどの処理以外で参照しかできない分処理は速いらしい
【C++】カレントディレクトリ配下のファイル一覧を抽出する
実装
sample03.cpp
//============================================================================ // Name : sample03.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <windows.h> #include <cstring> #include <unistd.h> using namespace std; int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! // カレントディレクトリを取得 char dir[512]; getcwd(dir, 512); cout << dir << endl; // 検索パス string str = ""; str.append(dir); str.append("/work/*.txt"); // 検索データ WIN32_FIND_DATA ffData; // 検索開始 HANDLE handle = FindFirstFile(str.c_str(), &ffData); if (handle == INVALID_HANDLE_VALUE) { cout << "取得失敗" << endl; } else { cout << "取得成功" << endl; do { // ファイル名を出力する string fileInfo = ""; SYSTEMTIME stFileTime; char strFileTime[256]; // 日付を変換 FileTimeToSystemTime(&ffData.ftLastWriteTime , &stFileTime); wsprintf(strFileTime , TEXT("%d年 %d月 %d日 %d時 %d分 %d秒") , stFileTime.wYear , stFileTime.wMonth , stFileTime.wDay , stFileTime.wHour , stFileTime.wMinute , stFileTime.wSecond); // 書式整形 fileInfo.append("file:"); fileInfo.append(ffData.cFileName); fileInfo.append(" "); fileInfo.append("最終更新日時:"); fileInfo.append(strFileTime); cout << fileInfo << endl; }while(FindNextFile(handle, &ffData));// 次のファイルを検索する // ファイルハンドルを閉じる FindClose(handle); } return 0; }
ディレクトリにサンプルファイルを準備
実行結果
!!!Hello World!!! C:\pleiades\pleiades-e4.5-cpp-jre_20160312\pleiades\workspace\sample03 取得成功 file:0001.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0002.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0003.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0004.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0005.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0006.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0007.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0008.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0009.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0010.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒 file:0011.txt 最終更新日時:2017年 8月 6日 2時 55分 42秒
pleiades(eclipse)のCDT(MinGW)でDLLを作成する
会社とかでするときとかさあ
VisualStudioないんですけど…
なんで買っといてくんないの(´・ω・`)
Community入れたくなるんですけど…
プロジェクトを作成する
共用ライブラリとして作成
ソースディレクトリと空のソースファイルを用意
実装
/* * sample01.cpp * * Created on: 2017/08/06 * Author: hogehoge */ extern "C" { __declspec(dllexport) /** * 加算 */ int add(int a, int b) { return a + b; } }; extern "C" { __declspec(dllexport) /** * 減算 */ int sub(int a, int b) { return a - b; } };
プロパティのリンカーフラグを追加
※「-static」を追加
ライブラリ名などを設定
※インポートライブラリ名を「libsample01.lib」を作成する
※defファイルとして「sample01.def」を作成する
ビルドを行う
Debugディレクトリ配下に作成されていることを確認
静的インポートで使用する
プロジェクトを作成する
プロパティのリンカーのその他のオブジェクトに「libsample01.lib」を追加
※リンカーフラグに「-static」も忘れずに追加
実装
//============================================================================ // Name : sample02.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; // エクスポート関数定義 extern "C" __declspec(dllexport) int add(int a, int b); extern "C" __declspec(dllexport) int sub(int a, int b); int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! cout << add(100, 40) << endl; cout << sub(100, 40) << endl; return 0; }
※ヘッダーファイル用意するのめんどかったので今回は直書きです。
ビルド
※「libsample01.dll」を配置しておくこと
実行
!!!Hello World!!! 140 60
できた感じです。
Azure Storage ServiceでBlobの読み書きをJavaで行う
pom.xml
<dependencies> <!-- https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage --> <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-storage</artifactId> <version>5.0.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> </dependencies>
実装
一覧出力
import java.net.URISyntaxException; import java.security.InvalidKeyException; import com.microsoft.azure.storage.CloudStorageAccount; import com.microsoft.azure.storage.StorageException; import com.microsoft.azure.storage.blob.CloudBlobClient; import com.microsoft.azure.storage.blob.CloudBlobContainer; import com.microsoft.azure.storage.blob.ListBlobItem; public class Sample01 { // 接続文字列 public static final String storageConnectionString = "DefaultEndpointsProtocol=http;" + "AccountName=自分のアカウント名;" + "AccountKey=自分のアクセスキー"; /** * 指定されたコンテナのblob一覧を取得するサンプル * @param args * @throws URISyntaxException * @throws InvalidKeyException * @throws StorageException */ public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException { // ストレージアカウントオブジェクトを取得 CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString); // Blobクライアントオブジェクトを取得 CloudBlobClient blobClient = storageAccount.createCloudBlobClient(); // blobの指定したtest01コンテナを取得 CloudBlobContainer container = blobClient.getContainerReference("test01"); // blob情報を出力する for (ListBlobItem blobItem : container.listBlobs()) { System.out.println(blobItem.getUri()); } } }
読み込み
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.security.InvalidKeyException; import com.microsoft.azure.storage.CloudStorageAccount; import com.microsoft.azure.storage.StorageException; import com.microsoft.azure.storage.blob.CloudBlobClient; import com.microsoft.azure.storage.blob.CloudBlobContainer; import com.microsoft.azure.storage.blob.CloudBlockBlob; public class Sample02 { // 接続文字列 public static final String storageConnectionString = "DefaultEndpointsProtocol=http;" + "AccountName=自分のアカウント名;" + "AccountKey=自分のアクセスキー"; /** * 指定されたコンテナのblobを読み込むサンプル * @param args * @throws URISyntaxException * @throws InvalidKeyException * @throws StorageException * @throws IOException */ public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException, IOException { // ストレージアカウントオブジェクトを取得 CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString); // Blobクライアントオブジェクトを取得 CloudBlobClient blobClient = storageAccount.createCloudBlobClient(); // blobの指定したtest01コンテナを取得 CloudBlobContainer container = blobClient.getContainerReference("test01"); // blobデータを読み込む CloudBlockBlob blob = container.getBlockBlobReference("testdata_20170716233116.txt"); InputStream input = blob.openInputStream(); InputStreamReader inr = new InputStreamReader(input, "UTF-8"); // 読み込んだ値を出力する String utf8str = org.apache.commons.io.IOUtils.toString(inr); System.out.println(utf8str); } }
書き込み
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.security.InvalidKeyException; import com.microsoft.azure.storage.CloudStorageAccount; import com.microsoft.azure.storage.StorageException; import com.microsoft.azure.storage.blob.BlobOutputStream; import com.microsoft.azure.storage.blob.CloudBlobClient; import com.microsoft.azure.storage.blob.CloudBlobContainer; import com.microsoft.azure.storage.blob.CloudBlockBlob; public class Sample03 { // 接続文字列 public static final String storageConnectionString = "DefaultEndpointsProtocol=http;" + "AccountName=自分のアカウント名;" + "AccountKey=自分のアクセスキー"; /** * 指定されたコンテナのblobを書き込むサンプル * @param args * @throws URISyntaxException * @throws InvalidKeyException * @throws StorageException * @throws IOException */ public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException, IOException { // ストレージアカウントオブジェクトを取得 CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString); // Blobクライアントオブジェクトを取得 CloudBlobClient blobClient = storageAccount.createCloudBlobClient(); // blobの指定したtest01コンテナを取得 CloudBlobContainer container = blobClient.getContainerReference("test01"); // blobデータへ書き込む準備 CloudBlockBlob blob = container.getBlockBlobReference("testdata_20170725000000.txt"); BlobOutputStream output = blob.openOutputStream(); // データを書き込む output.write("aaaaaaa".getBytes()); output.close(); } }