私のPCの中には色んなデータが入っています。 APNGとかSVGとかに手を出してるんで、まぁ色々です。 全部簡単にチェックできればいいんですが、まず全部表示できるようなヴューアが少ないです。 全部表示して整理できるようなソフトとかって、あるんでしょうかね? 作るわけには行かないしなぁ。
で、ふと気付いたのがブラウザ、これは万能ビューアですよね。 APNGでもSVGでも見れますし、音でも動画でもOK。 しかしローカルのファイルをチェックするには使い勝手が良くありません。 「何とか使えないかなぁ」と適当に検索してみたら、ちょっと気になるネタがありました。 「http 簡易サーバ」で検索するとC#でもjavaでもけっこう簡単にhttpのサーバが作れるようなんですよ。 もちろんインターネットに公開するようなサーバーを作るのは簡単ではないでしょうけど、ヴューアの部分をブラウザに頼った「ローカルファイル整理ツール」を作るハードルはかなり下がりそうです。
C#だと「System.Net.HttpListener」が、javaだと「com.sun.net.httpserver.HttpServer」が使えるようですね。 「データ整理ツールを作るんなら環境依存は少ない方がいいだろう」ってことでjavaの方を試してみました。 とりあえず考えながら作ったら、
- サーバはjavaアプリ、クライアントはブラウザ。
- サーバで用意した画像をブラウザで表示。
- サーバで用意したテキストをブラウザで表示。
- htmlでformを書く。htmlをブラウザで開いてformの編集情報をpost、サーバで受け取る。
というようなコードになりました。
import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.*; import java.net.*; public class JunkContentsBox implements HttpHandler { public final static int SERVER_RESPONSE_OK = 200; public final static int SERVER_PORT = 80; public final static int SERVER_STOP_DELAY = 10; private HttpServer _server = null; private Thread _serverThread = null; private byte[] _testImage; public static void main(String[] args) { JunkContentsBox thisApp = new JunkContentsBox(); thisApp.run(); } public void run() { readTestImage(); startServer(); WaitEnterKey(); stopServer(); } public void readTestImage() { InputStream in = null; try { URL url = this.getClass().getResource("test.png"); File file = new File(url.getFile()); in = url.openStream(); _testImage = new byte[(int)file.length()]; in.read(_testImage); } catch(Exception exc) { exc.printStackTrace(); } finally { if(in != null) { try { in.close(); }catch(Exception exc){} } } } public void WaitEnterKey() { System.out.print("Push enter to stop.\n> "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { br.readLine(); } catch(Exception exc) { exc.printStackTrace(); } } public void startServer() { System.out.println("Confirm a command : server start"); _serverThread = new Thread() { @Override public void run() { try { _server = HttpServer.create(new InetSocketAddress(SERVER_PORT), 0); _server.createContext("/", JunkContentsBox.this); _server.start(); } catch (IOException exc) { exc.printStackTrace(); } } }; _serverThread.start(); System.out.println("Server is started."); } public void stopServer() { System.out.println("Confirm a command : server stop"); System.out.format("Wait %d seconds...\n", SERVER_STOP_DELAY); assert _server != null && _serverThread != null; _server.stop(SERVER_STOP_DELAY); System.out.println("Server is stopped."); } @Override public void handle(HttpExchange ex) throws IOException { OutputStream os = ex.getResponseBody(); try { String uri = ex.getRequestURI().toString(); if(uri.equals("/test.png")) { ex.getResponseHeaders().add("Content-Type", "image/png"); ex.sendResponseHeaders(SERVER_RESPONSE_OK, _testImage.length); os.write(_testImage); } else { ex.getResponseHeaders().add("Content-Type", "text/plain"); String requestBody = getRequestBodyString(ex); String resTxt = uri + "\n" + requestBody; byte[] resBuff = resTxt.getBytes(); ex.sendResponseHeaders(SERVER_RESPONSE_OK, resBuff.length); os.write(resBuff); } } catch(Exception exc) { exc.printStackTrace(); } finally { try { os.close(); }catch(Exception exc){} } } private String getRequestBodyString(HttpExchange ex) { InputStream is = ex.getRequestBody(); try { ByteArrayOutputStream requestBuff = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int len; while((len = is.read(buff)) != -1) { requestBuff.write(buff, 0, len); } return URLDecoder.decode(requestBuff.toString(), "utf-8"); } catch(Exception exc) { exc.printStackTrace(); return ""; } finally { try { is.close(); }catch(Exception exc){} } } }
クラス名は「最終的にそんなのができたら良いなぁ」という妄想ですな。 とりあえずコンパイルして、クラスと同じフォルダに適当な「test.png」を用意。 次のhtmlも用意です。
<html> <head></head> <body> <form action="http://localhost/testContext" method="post"> <p>入力1 : <input type="text" name="text1" value="あいうえお" size="20" /></p> <p>入力2 : <input type="text" name="text2" value="かきこけこさしすせそ" size="20" /></p> <p>入力3 : <input type="radio" name="radio1" value="表示1" checked="checked">表示1</input> <input type="radio" name="radio1" value="表示2" checked="checked">表示2</input> <input type="radio" name="radio1" value="表示3" checked="checked">表示3</input> </p> <p><input type="submit" name="submit" value="送信" /></p> </form> <img src="http://localhost/test.png"/> </body> </html>
htmlファイルのパスは適当でOK。
コマンドプロンプトで実行したら「なんたらかんたら ... Push enter to stop.」と表示されて止まります。 表のスレッドはenterキー待ち、裏のスレッドでサーバを動かしています。 この状態でブラウザで↑のhtmlを開くとformと「test.png」が表示されます。 formはhtmlの内容なのでローカルファイルをそのまま表示、「test.png」は「src="http://localhost/test.png"」なのでサーバが送った画像が表示されています。 formの送信ボタンを押すとパラメータがpostされてサーバに届きます。 その内容はtext/plainで応答。 htmlにしなかったのは手抜きですけど、まぁ多分htmlにしたらブラウザもそう受け取ってくれていたでしょう。 コマンドプロンプトでenterキーを押したらサーバの停止です。
数時間で作ったコードなんでところどころマズいですね。 って言ったらダメなのか、腕のいい人はパッと作ったものが良品といいますしね。 ちょいと反省。 で、こんな私でも数時間で簡易サーバを作れるってのはいい時代です。
ローカル専用と割り切ってセキュリティをぬるめにすれば「formの情報を元にローカルファイルをガリガリ」とかってのは、「GUIもjavaで全部コーディング」ってのと比べて楽になりそうです。 firewallはちゃんとしないとダメでしょうけど。
あれ? なんか文章が整理ツール作る方に行ってる? 無理ですから。