• ベストアンサー

戻り値の返し方

java eclipseを使ってプログラミングを勉強しています。 通信のプログラムを作っているのですが、 データをwrite()メソッドやread()メソッドを使って 送受信するのですが、それらのメソッドが正常に動いたかの 確認をする必要があると考えました。 そのためには、戻り値を確認すればよいことが分かりました。 初歩的な質問で申し訳ないですが、どうやって戻り値を 確認すればよいでしょうか? アドバイスをお願いします。

  • Java
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • henagisan
  • ベストアンサー率100% (2/2)
回答No.1

質問が抽象的なので具体的にするともっと回答しやすくなると思います。 質問の意図に沿っているかわかりませんが、メソッドの戻り値を確認する方法だけお答えします。 read()の戻り値は「読み込まれた文字数」をintで返します。 ストリームの終端に達し、読み込める文字がなくなった場合「-1」を返します。 たとえばreader.read()というようにメソッドを呼び出した場合、 reader.read()自身が読み込んだ文字数を表します。 たとえば以下のように記述します。 if(reader.read() == -1){    System.out.println("もう読み込めません"); } write()は返り値が無いため、確認することは出来ないと思います。 基本的に入出力ではtry catchを用いてエラー処理をするので、正常に動かなかった場合はcatch(){}のなかで処理をすればいいです。 最後に、もしソケット通信を行っているなら以下のページが参考になるかと思います。read()やwrite()すら使わなくてかけます。 http://www.hellohiro.com/socket.htm http://ysserve.int-univ.com/sugsi/Lecture/java/L5/05-03-02.html

debukawa
質問者

お礼

回答ありがとうございます。 具体的に書きます。 for (int i = 0; i < data-2; i++) {   out.write(i); } out.write('\\'); out.write('s'); out.flush(); out.write('\\'); out.write('q'); out.flush(); という処理を行うのですが、本当にdata-2が書き込まれて送信されたのか、 また、 while ((ch = in.read()) != -1) {   if (stat == STATUS_RST) {    startNs = System.nanoTime();    stat = STATUS_RCV;   }   if (stat == STATUS_RCV && ch == '\\') {    stat = STATUS_CMD;   } else if (stat == STATUS_CMD) {    if (ch == 's') {     long Ns = System.nanoTime() - startNs;     long Micros = Ns / 1000;     out.println(Micros);     System.out.println("計測時間:" + Micros + " (マイクロ秒)");     stat = STATUS_RST;    } else if (ch == 'q') {     break;    } else {     stat = STATUS_RCV;   }  } } この処理で本当に送信されたバイト数が受信されたのかを 戻り値を使って確認したいのです。 >read()の戻り値は「読み込まれた文字数」をintで返します。 >ストリームの終端に達し、読み込める文字がなくなった場合「-1」を返します。 ということは、戻り値をチェックすれば、現在何バイト読み込んだかが 確認できるということでしょうか?

その他の回答 (2)

  • komi1341
  • ベストアンサー率65% (25/38)
回答No.3

まず一点訂正です。 >4 x 115 + 1バイトまでで受信側が計測を終了してしまうような。 APIリファレンスの記載に疑問を感じ挙動を確認したところ、4 x 115 + 1 ではなく 115 + 1 のようです。write(int) は引数はintなのにbyteとして送信するのですね。失礼致しました。 が、いずれにしてもご提示頂いたコードで10000バイトのデータを送信できないことに変わりはありません。 > ということは、次のようにすればよいですか? そうです。以前もお願いしましたが、聞き返す前にご自身で確認して頂けませんか? 確認のためだけに再度回答を求められるのは困ります。 > fulsh()で送信されるということですよね? > outというバッファの中にforのなかの処理で作られたバイトデータを格納して、fulsh()で送信していると考えています。 flush()を呼ぶとバッファリングされていたデータが強制的に出力ストリームに書き出されます。おおまかな解釈は合っていると思いますが、そこまで分かっていてあと何を知りたいのでしょうか。結局私の「flush()の挙動を疑っているのか」という問いに戻ってしまうように思います。やりとりが大変そうなのでこの件の回答は保留とさせて頂きます。 > forの中の処理で、次のようなデータを作ろうとしています。 > 012345678...9999s この例から察するに、送信側が out.write(9999) としたら受信側は "9999"という4文字の文字列として認識するとお考えですか? それとも '9999' という文字が存在すると思っているのでしょうか? いずれも不正解です。 試しに送信側のforループとwrite()を全部コメントアウトして、代わりに write(116) を実行してみてください。その後でwrite('t')に変えて実行してみてください。その結果がなぜそうなるのか人に説明できないようでしたら、「アスキーコード」で検索してみてください。これは「なぜ115 + 1バイトで受信が終了するのか」の間接的な回答にもなります。 このあたりはプログラミングというより、コンピュータの基礎知識に相当する内容です。最初の質問である「戻り値」の件や、以前からのご質問もそうですが、ナノスケールの時間測定という高度なことに挑戦するにしては質問が初歩的すぎると感じます。コーディングを見てもナノスケールにこだわるにしては正直レベルが低いです。お急ぎの理由があるのかもしれませんが、コンピュータ/プログラミング/通信の基礎といった本を読んで、先に基礎をきっちり抑えておかないと厳しいと思いますよ。

debukawa
質問者

お礼

回答ありがとうございます。 おっしゃるとおりです。自分のレベルとやっていることがあっていないですよね。不愉快な気持ちにさせてしまい、申し訳ありません。 私はjavaはまだ半年ほどしか勉強していません。それも、独学です。 詳細を書くと、特定されるのでかけないですが、ある事情で高いレベルの作業をしています。 先生は質問しても返事をしてくれませんので、頼るところがネットしか ありません。たくさんサイトを見ますが、初心者ですので満足に理解できません。 期限までに時間がないので、わらにもすがる思いで質問しています。 なんとかして完成させないと、4月から職なしになってしまいます。 こんなことは、komi1341さんには何の関係もないので無視していただいて結構です。 ただ、自分で考えるのが面倒だからとか、そういう理由で質問させていただいていたのではないです。 長々と書いてしまいました。 自分でもできる限り勉強しますが、それでもできないときは、また質問させていただきますので、よろしければアドバイスをお願いします。

  • komi1341
  • ベストアンサー率65% (25/38)
回答No.2

inやoutは何というクラスのオブジェクトでしょうか? 上下に分かれているコードはおそらく送信側、受信側のコードですよね。だとすると別々のコードなのにoutという同名の変数があるので紛らわしいです。 メソッドの戻り値についてはAPIリファレンスで確認できます。 http://java.sun.com./javase/ja/6/docs/ja/api/index.html 引数なしのread()なら、おそらくこれでしょう。 http://java.sun.com./javase/ja/6/docs/ja/api/java/io/InputStreamReader.html#read() 読んで頂ければ分かりますが、引数のあるread()の戻り値は「読み込まれた文字数」になりますが、引数のないread()の戻り値は読み込んだ文字そのものです。よって while ((ch = in.read()) != -1) { // 省略 } というループであれば、ループ内に処理が移った回数が読み込まれた文字数と等しくなるはずです。ループの外でループカウント用の変数を定義して、whileループの中でそれをインクリメントしてやれば、現在の読み込み文字数が分かるのでは。 > 本当にdata-2が書き込まれて送信されたのか flush()の挙動が信じられないということでしょうか? そもそも質問者さんはデータが「どこに」書き込まれて「どこまで」送信されたら「送信された」とみなしたいのでしょうか。そのあたりが曖昧なまま、やみくもに質問されているように感じます。 ついでに、 for (int i = 0; i < data-2; i++) {   out.write(i); } これだとdataがどれほど大きくても、4 x 115 + 1バイトまでで受信側が計測を終了してしまうような。想像ですが、送りたいのはiではなくてdata配列の中身なのでは? また out.write('\\'); これも不要に見えます。これが2行あることで、8バイト余計にデータが送信されますがそれで問題ないのでしょうか?

debukawa
質問者

お礼

回答ありがとうございます。 質問後に、すこしプログラムの内容を変更しました。 以前は、受信にかかる時間を計測し、結果をかえす処理を行う予定でした。よってout.println(Micros);としていました。 変更後は、受信したバイト数を確認し、確認したバイト数分のデータを 送信側に送ろうと考えています。 そのプログラムを書きました。送信側でデータを次のように作成しています。 Socket sock = new Socket(host, port); BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); for (int i = 0; i < Data - 1; i++) {  out.write(i); } out.write('s'); out.flush(); Dataは送信するバイト数で自分で指定するようになっています。 受信側では、次のように受信します。 BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); long startNs = System.nanoTime(); while ((ch = in.read()) != -1) {  if (ch == 's') {   long Ns = System.nanoTime() - startNs;   Micros = Ns / 1000; } この後、同様にして届いたバイト数文のデータを送信側に送ろうと考えています。 >現在の読み込み文字数が分かるのでは。 ということは、次のようにすればよいですか? int count; while ((ch = in.read()) != -1) {  if (ch == 's') {   long Ns = System.nanoTime() - startNs;   Micros = Ns / 1000; } count++; } >flush()の挙動が信じられないということでしょうか? そもそも質問者さんは >データが「どこに」書き込まれて「どこまで」送信されたら「送信された」とみなしたいのでしょうか。 fulsh()で送信されるということですよね? outというバッファの中にforのなかの処理で作られたバイトデータを格納して、fulsh()で送信していると考えています。 Data=10000とすると、 forの中の処理で、次のようなデータを作ろうとしています。 012345678...9999s sまで送信されたら送信完了としたいです。 >4 x 115 + 1バイトまでで受信側が計測を終了してしまうような。 Dataはint型で送信したいデータのバイト数で、その数値分のバイトを送りたいです。どうして4 x 115 + 1バイトまでで終了するのでしょうか? 質問だらけですいません。

関連するQ&A

  • 戻り値について

    javaの勉強をしている者です。 初歩的な質問で申し訳ありませんが、 メソッドの戻り値を確認するためには、 returnをつかわければいけないですか? それとも、例えばread()だと、 ch=read();とすれば、データの次のバイトを取得する と思うんですけど、この方法でも戻り値を 確認したということになるのでしょうか? ちがうのであれば、説明していただけると幸いです。

    • ベストアンサー
    • Java
  • VBAでの戻り値と引数について

    最近VBAでプログラムを勉強しています。 引数と戻り値について教えてください。 定義としては、 引数:プロシージャに渡される定数、変数、および式。 戻り値:呼び出し元に処理の結果を戻す値。 となっているのですがいまいちピンときません。 SubプロシージャとFunctionプロシージャでその違いがあると思うのですが、具体的にどれが引数でどれが戻り値なのかわかりません。 他のプログラミングも全く経験がない初心者で初歩的な質問ですみませんがご教授お願いします。

  • シリアル通信でのread関数の戻り値

    オムロン製PLCと上位コンピュータをRS232Cで接続し、FINSコマンドを用いてシリアル通信をしようとしています。 現在作っているプログラムの流れは、 ・シリアルポート"/dev/ttyS2"のオープン   comm_fd = open("/dev/ttyS2", O_RDWR | O_NOCTTY); ・通信設定   termios構造体を設定 ・コマンドフレーム(COMMAND)を作成し、ポートに書き込む   write(comm_fd, &COMMAND, strlen(COMMAND)); ・PLCからのレスポンスを読み出す   read(comm_fd, &RESPONSE, 256); のようにしているのですが、read関数が実行されたままになってしまいます。(エラーコードも返ってこない状態です) readの戻り値が-1ならポートにアクセスできていないとわかるのですが… ためしにcomm_fdと違う値をread関数に入れてみたところ(read(6, &RESPONSE, 256)、戻り値は-1となりました。 これはどういう状態になってしまっているのでしょうか? わかりにくい質問で申し訳ありません。

  • メソッド宣言の戻り値の型にクラス名を使うには?

    メソッドの戻り値の型にクラス名を使ってるプログラムを見かけたのですが、例えばクラス名を public class Player{ とします。そして Playerクラスのメソッド宣言に  private   Player(戻り値の型) startRun(メソッド名) { とあります。 これは戻り値の型にクラス型の変数を使ってユーザー定義してると思うのですが使い方が分かりません。 javaのサイトはできるだけ調べたのですが戻り値の型にクラス名を使うにはどうすればいいか分かりませんでした。 この使い方を教えてくれるサイトを教えてください。 基本型と参照型のStringクラスについて教えてくれるサイトはたくさん見かけたのですが…。 お願いします。

    • ベストアンサー
    • Java
  • 戻り値を使う問題について

    <問題> 以下のクラスを作成せよ。 「mainメソッド」 1)Aisatuクラスのオブジェクト作成。 2)Aisatuクラスのohayouメソッドを呼び出し、  戻り値を取得して表示する。 3)Aisatuクラスのkonnitiwaメソッドを呼び出し、  戻り値を取得して表示する。 4)Aisatuクラスのkonbanwaメソッドを呼び出し、  戻り値を取得して表示する。 「Aisatuメソッド」 ohayouメソッド ・「おはようございます」という文字列を戻り値とする。 ・「こんにちは」という文字列を戻り値とする。 ・「こんばんは」という文字列を戻り値とする。 <実行結果> おはようございます こんにちは こんばんは ************************************************************ 上記の質問についてのプログラムなんですが、いまいちクラスとか メソッドとかよく分からなくて、ちゃんと実行できません。 コンパイルは通るのですが、実行しようとすると、 java.lang.NoSuchMethodError のエラーが出てしまいます。 メソッドが見つからないということでしょうか? 間違っているところを教えて下さい。 よろしくお願いします。 class Aisatu { private String oha; private String koni; private String koba; public String aiOhayou(String o) { oha = o; return oha; } public String aiKonnitiwa(String n) { koni = n; return koni; } public String aiKonbanwa(String b) { koba = b; return koba; } } class Greet02 { public static void main(String args[]) { Aisatu as = new Aisatu(); as.aiOhayou("おはようございます"); String ohayou = as.aiOhayou("おはようございます"); System.out.println(ohayou); as.aiKonnitiwa("こんにちは"); String konnitiwa = as.aiKonnitiwa("こんにちは"); System.out.println(konnitiwa); as.aiKonbanwa("こんばんは"); String konbanwa = as.aiKonbanwa("こんばんは"); System.out.println(konbanwa); } }

    • ベストアンサー
    • Java
  • ソケットのrecvの戻り値が0

    linuxにてソケットの勉強をしようと思い、 簡単なソケット通信のプログラムをCで組みました。 ret = recv(ID, Buff, sizeof(Buff), 0); といった感じでサーバ側を組んだのですが、 この戻り値retに0が入ることがあり、思うように動いてくれません。 私の認識だと、recvは受信するまで待ち、 受信したサイズを返すと思っているのですが、 それが0とは、いったいどういう意味を持つのでしょうか?

  • InputStreamにたまったデータを消す方法

    InputStreamにたまったデータを消す方法 私は現在勉強のためにsocketプログラミングをJavaでしているのですが困った事があります。それはInputStreamからreadでデータを読み込んでも、読み込んだデータはStream内に消えずに残っているため、処理が複雑になってしまいます。何かflushのようなstreamにたまったデータを吐き出すメソッドはないのでしょうか?

    • ベストアンサー
    • Java
  • eclipse java18 日本語文字化け

    java18を使用してeclipse4.24でプログラムを実行すると日本語が文字化けして困っていま。 改善方法が分かりません。 現状までの流れ 1.JAVA18をインストール その後統合開発環境を使用したくeclipse2022-06 (4.24.0)をインストール 2.eclipseを使用しjava勉強の為プログラム作成し実行   この時eclipseの実行結果が表示される画面には日本語が正常に表示された。 3.いくつかプログラムの作成/実行を繰り返していた時、実行されているコンパイラはjava17であることが分かった。 先にjava18をインストールしていた為 java18でコンパイル等していたと思っていた。 4.eclipseにおいてJava18を設定しプログラム作成実行したところ日本語が化けてしまった。 5.web上で検索してeclipse.iniに-Dfile.encoding=UTF-8を追加しても変化なし 6.eclipseにてJREを17に戻して実行すると、日本語表示が正常に戻ります。 eclipseでjava18のJREの登録が間違っているのだと思いますが、現状何をどうしたら良いのか分かりません。 ご存知の方お力添えお願い出来ないでしょうか? ※java18そのもののインストールにミスがあるのかと思い、ウィンドウズのコマンドプロンプトでプログラムをコンパイル/実行をしてみたところ日本語は正常に表示されましたのでjava18のインストールはうまくいっているようです。

    • ベストアンサー
    • Java
  • SOAPで画像データを送信する

    質問させてください。 勉強目的で、Eclipse+JAVAでSOAP通信をおこなうプログラムを作成しています。 (将来的にはAndroidでSOAP通信を行うプログラムの作成を目標にしています。) SOAPで文字の送信を行う事まではできたのですが、画像ファイルを送信することはできないのでしょうか。 可能であれば、サンプルページなどをありませんでしょうか。 突然の質問で申し訳ありません。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 基本情報処理技術者 平成24年度秋 JAVA

    javaのプログラミングは長らくやっていない状態で、問題を解き始めましたが、 プログラムが追えず困っています。 初歩的な質問になってしまいますが、下記についてどなたか教えてください。 1.プログラム3のmainメソッドにて new TimerTest().test(); とありますが、mainメソッドが所属しているクラスはTimerTestですよね? 自クラスってnewしないといけないんでしょうか。 また、newしているのに、インスタンスをTimerTest型の変数に格納しなくていいのでしょうか。 2.プログラム3のtimeメソッドにて、 longTimer = Timer.createTime("long timer",..................) とありますが、これはプログラム2のTimerクラスのメソッドを呼び出していますよね? 他クラスなのに、newしなくても使えるんでしょうか。 Timerクラスがpublicだからnewしなくていいという解釈であっていますか? それともcreateTimerメソッドがstaticだからでしょうか? Timer.createTimeのTimerは、クラス名なのか、 createTimeメソッドの形名?なんでしょうか。 初歩的なところですみません・・・ この質問を見て「このあたりが理解できていない」というような感じ方がありましたら、 そこを勉強したいのでご教示お願いします。

専門家に質問してみよう