福ちゃんの駄文

Loading...

calendar

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
28293031   
<< October 2018 >>

categories

archives

スポンサーサイト

0
    記事を表示する 記事を非表示にする

    一定期間更新がないため広告を表示しています

    • 2018.08.22 Wednesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    Java初心者が考えたファイルの読み書き方法~某講義の試問回答例~

    0
      記事を表示する 記事を非表示にする

      大学のある講義でJavaプログラミングの勉強をするものがありまして、その講義では毎週いくつかの「試問」が出題されていました。

      試問といっても「テキストファイルを読み込み、そのまま別のテキストファイルに出力するプログラムを作る」とか簡単なものでしたが、これがプログラミング初心者には結構大変なものでした。この記事では、(後学の参考になるかは不明ですが)その試問に対する私の回答例を掲載したいと思います。

       

      なお、当然ですがこの回答例は大学および担当教授などが一切関わったものではなく、初心者がたどたどしく書いた回答例の1つに過ぎません。したがってここに示す回答にはいくつかの間違いがあるかもしれませんし、試問の模範解答として示されるものでは全くないことにご注意ください。

       

      以下に示す全コードはGithubで公開中です。実際に動かして試すなどする場合はあらかじめローカルに落としておいてください。

      https://github.com/ia15076/deshopuro

       

      開発には講義中に紹介されたIDEであるeclipseを使用しています。その他、動作には以下のものが必要です。

      • Maven
      • (OpenClの動作環境;CUDA Toolkitなど)
      • (Lombok)

      OpenCLはAparapiを動かすのに使いますが、学部推奨PCはGPUを積んでいないので不要かもしれません(JTPモードで動作はするはず)。またLombokも、使ってるんだから一応eclipseに入れとこうってだけであって今回のコードを動かすだけなら不要かもしれません。面倒ならLombokのアノテーションは消しちゃってください。

       

      ***

      試問4

       

      「あるディレクトリ以下の全テキストファイルを読み込み、内容をコンソールと他ファイルに出力する」

       

       

      テキストファイルを読み込んでそのまま書き出すだけのシンプルな課題ですが、Javaの場合ファイルを読み込むというだけのことにも古い方法、かつては新しかった方法、今新しい方法と色々な方法があってどれを選べば良いのか分り辛いです。もちろん新しい方法のほうが良いに決まっているのですが…

      今回は、「まずファイルパスを受け取って、そのファイルの内容を読み込んで返すTCPサーバを作り、次にソケット通信でそのサーバとやり取りするクライアントを作る」という方法で行きましょう。

       

      まずはサーバ側です。

      比較的最近(Java7)に追加された、nio2のAsynchronousServerSocketChannelを使います。

      29行目のacceptがCompletionHandlerでクライアントから通信があったときの処理を登録している部分、48行目の#accepted(InetSocketAddress)メソッドがその実際の処理を書いている部分です。

       

      次にクライアント側です。

      こちらもAsynchronousSocketChannelを使っています。#readBytes(InetSocketAddress)が実際にサーバと通信している部分です。

      こちらのメインメソッドを走らせれば、./file/read/にある全ファイルを読み込み、./file/write/にそのまま書き出してくれるはずです。

       

      ***

      試問5

      「単一のファイルを書き込む・読み込むメソッドを作る」

       

      書き込む文字列をString型の引数に受け取ってテキストファイルに書き込むメソッドを作れという課題ですが、テキストファイルへの書き込みというのは簡単に見えて意外に難しい作業です。

      講義中に解説された通り、コンピュータが扱えるのは数字だけであって文字そのものを扱うことはできません。したがって普通に文字列が書いてあるように見えるテキストファイルも…

      実際のところは「文字コード」の羅列であって、中身はこうなっています。

      とはいえ、Javaは内部的にはUTF-16という文字コード体系を使っており、かつString#codePoints()という便利なメソッドもあるのでUTF-16のテキストファイルを作るならそれほど難しい変換は必要ありません。

      したがって今回は、「引数で受け取ったStringをUnicodeコードポイントの配列に変換し、これをGPUを用いた演算でバイト配列にエンコード、先頭にUTF-16LEのBOMを付けてテキストファイルに書き出すメソッドを作る」という方法で行きました。

       

      実際の実装はこうです。

      追加でコンストラクタを使うという課題要件もあったので、ファイルを読み込む際のバッファサイズを表すメンバ変数を適当に作ってコンストラクタで代入できるようにしておきました。

      #write(Path,String)で行っているエンコード作業ではAparapiを使ってGPUに働かせています。

       

      ***

      試問6

      「ファイル出力時に行が指定以上の大きさの行のみ出力する」

       

      今までテキストファイルの入出力を行うプログラムを作ってきましたが、この出力時に「各行の文字列の大きさが指定以上かどうか」のチェックをかけて、指定以上の大きさの行のみ出力するようにしよう、という課題です。要は小さい行を削除したテキストファイルを書き出すことになります。

      行の大きさチェックというと各行ごとに文字数をカウントするのが良さそうに思えますが、これにはString#length()を1回呼び出すという極めて複雑かつ困難な手順が必要なので他の方法を考えました。

      今回は「各行の文字列をモールス信号のwavファイルとして出力し、このwavファイルの大きさで行の大きさを判定、大きさが指定以上の行を別のテキストファイルに出力する」という方法で行きます。

       

      先にモールス信号の書き出しを行うクラスを作りました。実装はこうです。

      入力文を一文字ずつ符号に変換して短形波で書き出しています。

      アルファベットとモールス信号の符号の対応については、モールス符号一覧表 - JR7IBWを参考にさせて頂きました。

       

      試しに「ago no pose」という音声を書き出してみた例です。

      https://soundcloud.com/user-236115439/ago-no-pose

      後はこれを使って各行の文字列のモールス信号を音声ファイルに書き出し、ファイルサイズからその行を出力したりしなかったりする処理を書くだけです。このように実装しました。

      ***

      いかがでしたでしょうか?Java初心者ですので至らない点も多数あったかと思いますが、なんとか試問の要件を満たした実装をすることができたかと思います。

      Java上級者の方で何か気になることなどありましたらぜひコメントなどでご指導のほどよろしくお願いします。

       

      では、今日のところはこの辺でノシ

      Check

      スポンサーサイト

      0
        記事を表示する 記事を非表示にする
        Check
        • 2018.08.22 Wednesday
        • -
        • 18:00
        • -
        • -
        • -
        • -
        • by スポンサードリンク

        コメント
        コメントする








           
        この記事のトラックバックURL
        トラックバック

        Locate Muter

        GPS情報からノートPCなどの現在位置を取得し、職場や学校にいる場合は自動的にミュートを行ったり、自宅にいる場合は自動的にミュートを解除したりできるWindowsアプリケーションです。

        GPSに誤差が出ない限りはミュート忘れ事故を高確率で防ぐことができます。

        講義中にミュート忘れで大きな音を響かせた、あの悲しみを二度と味わわないためにどうぞ。

        なおWindowsで位置情報を取得できるのは8からだそうなので、それ以前のバージョンのWindowsでは使えないかもしれません。

        製作中

        弾幕 via ついったー

        Twitterにストリーミング接続し、受信したツイートをニコニコ動画のようにデスクトップに流すWindowsアプリケーションです。

        ユーザータイムラインを受信するほか、特定のワードやハッシュタグのついたツイートを追うこともできます。

        プレゼン中にTwitterから質問や意見を受けたい時、または別作業中にTLを見たいとき、何かのネタにしたいときなどにどうぞ。

        相互リストメーカー

        Twitterの「リスト」機能で、相互フォローのユーザーを含んだリストを作るだけのアプリケーションです。

        詳細ページ:準備中

        つぎツイ

        自分のツイートをRTした人が、次になんて呟いてるのかとか気にならない?ならない?私だけ?

        きっと私だけではないと思うので作りました。RTに限らず何らかのワードを呟いた「次」のツイートを見つけてcsvに出力することができます。

        詳細ページ:準備中

        KIRIBAN

        大学の講義で製作中のWebサイトです。うまくできたらみんなで使えるようにするかも?

        製作中

        自己紹介。サイトリニューアルにつき準備中