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(); } }
scoket.ioで下層パスごとに処理を記載する
パス別に処理を分割したいみたいな…
ホスト名は実際のwebサイトみたいに扱って/hogehoge1、/hogehoge2とかでsocket通信したいみたいな感じですかね
やったこと
下層パスを用意して、処理を記載。
クライアントもそれに合わせたURIを指定してアクセス
実装
サーバ側
var io = require('socket.io').listen(3000); // 下層パス1 io.of("/hogehoge/test1").on("connect", socketFunction1); // 下層パス2 io.of("/hogehoge/test2").on("connect", socketFunction2); // 接続処理1 function socketFunction1(socket) { console.log("/hogehoge/test1: connected"); // メッセージ var msg = { "client": "client_" + (new Date()).getTime(), "msg": "接続OKです。" }; socket.emit("client_info", msg); // 切断 socket.on("disconnect", function() { console.log("/hogehoge/test1: disconnected"); }); // メッセージ受信 socket.on("message", function(data) { console.log("送信:" + data); }); } // 接続処理2 function socketFunction2(socket) { console.log("/hogehoge/test2: connected"); // メッセージ var msg = { "client": "client_" + (new Date()).getTime(), "msg": "接続OKです。" }; socket.emit("client_info", msg); // 切断 socket.on("disconnect", function() { console.log("/hogehoge/test2:" + "disconnected"); }); // メッセージ受信 socket.on("message", function(data) { console.log("送信:" + data); }); }
クライアント1
var client = require("socket.io-client"); var socket = client.connect("http://localhost:3000/hogehoge/test1"); // 接続 socket.on("connect", function() { console.log("/hogehoge/test1: client connected"); }); // メッセージ受信 socket.on("message", function(data) { console.log("/hogehoge/test1:" + "受信文字:" + data); }); // 接続情報 socket.on("client_info", function(data) { clientId = data.client; console.log("client:" + clientId); }); // 5秒後に切断 setTimeout(function() { socket.disconnect(); }, 5000);
クライアント2
var client = require("socket.io-client"); var socket = client.connect("http://localhost:3000/hogehoge/test2"); var clientId = ""; // 接続 socket.on("connect", function() { console.log("/hogehoge/test2 client connected"); }); // メッセージ受信 socket.on("message", function(data) { console.log("/hogehoge/test2: " + "受信文字:" + data); }); // 接続情報 socket.on("client_info", function(data) { clientId = data.client; console.log("client:" + clientId); }); // 5秒後に切断 setTimeout(function() { socket.disconnect(); }, 5000);
所感
サーバ側はそれぞれ用意しないといけないのと同じでクライアントもURIを指定する必要がある。
まあ、サーバで設定するイベントの使用可否が変わってくるはずなのでこの辺の問題は受け入れる事となる。
実際にhttp://localhost:3000/sample1みたいなURIのsocket.io通信自体はあるのでその設定自体がわかっただけでも良いこととなりました。
最初はwebサーバとかでなんかしないといけないとか考えてて面倒くさいと思っていたのでちょっと楽になった感じ
javascriptはjqueryしか使っていないのでnodejsをもう少し勉強してjavascriptの知識向上に役立てたい。
nodejsのsocket.ioのサーバにJavaで作成したクライアントで接続する
ソケット通信のサンプルって
基本TCP/IP関連のやつなんですね。
まあ、わかりますけど、websocketとか使う際はどんなデータが流れてくるとかどんな手法で送信したらよいとかちょっとわかりづらい事があります。
今回はJavaでsocket.ioのサンプルを探して見ました。
簡単なやつですけど助かりました。
実装
サーバ側
var io = require('socket.io').listen(3000); // 接続 io.sockets.on("connect", function(socket) { console.log("connected"); // 接続後にクライアントへ送信する socket.emit("message", "接続OKです。"); // 切断 socket.on("disconnect", function(data) { console.log(data); console.log("disconnected"); }); // メッセージ受信 socket.on("message", function(data) { console.log("送信:" + data); }); });
クライアント側
package socket_sample01; import java.net.URISyntaxException; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; public class Sample01 { private static Socket socket; public static void main(String[] args) throws URISyntaxException, InterruptedException { socket = IO.socket("http://localhost:3000"); // サーバーからのmessageがemitされた時 socket.on("message", new Emitter.Listener() { public void call(Object... objects) { // 最初の引数を表示 System.out.println(objects[0]); //サーバー側にmessageで送信 socket.emit("message", "This is Java"); } }); // 接続開始 socket.connect(); // タイマーようのタスク class SampleTask extends TimerTask { /** このメソッドがTimerから呼ばれる */ @Override public void run() { System.out.println("タスク実行:" + new Date()); // 切断処理 socket.disconnect(); } } // 一定時間後に処理を切断するように指示 TimerTask task = new SampleTask(); Timer timer = new Timer("myTimer"); System.out.println("処理開始:" + new Date()); timer.schedule(task, TimeUnit.SECONDS.toMillis(3)); //3秒遅延させる TimeUnit.SECONDS.sleep(5); timer.cancel(); System.out.println("処理終了"); } }
クライアントのライブラリ
<dependencies> <dependency> <groupId>io.socket</groupId> <artifactId>socket.io-client</artifactId> <version>1.0.0</version> </dependency> </dependencies>
所感
簡単な接続自体はできた。
単純なメッセージではなく、配列とかクラスのようなデータの場合はどのような設定で送信すればよいのかちょっと調べてみよう。