質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • Java

    16757questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Javaでファイルのランダムアクセスを行いたい

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 795

aiueoaiueoaiue

score 88

実現したい事

Javaでテキストファイルの任意の位置から読み込むというソースを書きたいのですが、出力結果を確認してみるとテキストファイルの中身ではなくバイト数が表示されてしまいました。おそらくサンプルを軽く見ただけで理解が完全には及んでいないんだと思うのですが、テキストの文字列を表示させる方法が分かる方回答お願いします。

該当ソース

import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.Charset;

public class sample{
    public static void main(String[] args) throws IOException {
        // 読み込みモード
        Path path = Paths.get("./", "sample.txt");
        SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);
        // ファイルサイズ取得
        long fileSize = channel.size();

        // 取得のためのバッファを用意
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Charset charset = Charset.forName("UTF-8");
        // 末尾(fileSize-1)から1024byteを取得
        channel.position(fileSize - 1 - 1024);
        System.out.println(channel.read(buffer));
        charset.decode(buffer);
        System.out.println(buffer);
    }
}

補足

ソースは現時点ではファイルの最終行を表示させるというソースのつもりです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • spookybird

    2018/09/09 11:01

    「サンプルを軽く見ただけで理解が完全には及んでいないんだと思う」のなら、サンプルをしっかり読み込んでもう少しご自身で理解を深めてみてはいかがでしょう。焦らず一歩一歩やっていくといいと思いますよ。

    キャンセル

回答 2

0

SeekableBypeChannel.read()はファイルから読み込んだデータをバッファに書き込んで、読み込んだバイト数を返します。今のコードでは、その読み込んだバイト数だけを出力しているだけになっています。データはbufferに書き込まれていますが、何も処理していません。

bufferの中身を出力するようにしてください。しかし、bufferByteBufferであるため、そのままでは文字列として認識されません。ファイルの中身の文字コードのCharsetを作り、Charset.decode()CharBufferに変更してから、printlnに渡してみてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/10 02:01 編集

    プログラムを修正してみたのですが、出力が
    java.nio.HeapByteBuffer[pos=1024 lim=1024 cap=1024]
    となってしまいました。これはどこが間違っているのでしょう?

    キャンセル

  • 2018/09/14 18:55

    charset.decode(buffer)はbufferをもとにCharBufferを返します。buffer自体がCharBufferに変わるわけではありません。charset.decode(buffer)の結果を適当な変数に代入し、それをprintlnしてください。

    キャンセル

  • 2018/10/19 18:22

    channel.read(buffer);
    CharBuffer abc = charset.decode(buffer);
    System.out.println(abc);としたら何も出力されなくなりました。これは何がいけないのでしょうか?

    キャンセル

0

とりあえず適当なファイルの中身を出力だけしてみました。

入力ファイル

イメージ説明

出力結果

イメージ説明

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class memo_qa145601 {

    public static void main(String[] args) throws IOException {
        // 読み込みモード
        Path path = Paths.get("C:\\workspace\\tmp\\", "sample.txt");
        SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);
        // ファイルサイズ取得
        long fileSize = channel.size();

        // 取得のためのバッファを用意
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 末尾(fileSize-1)から1024byteを取得
        channel.position(fileSize - 1 - 1024);


        //以下追記です
        //バッファに読み込み
        channel.read(buffer);

        //一旦byte[]配列に入れる
        byte[] bytes = buffer.array();

        //char型にキャストして文字列を出力
        for(byte b:bytes) {
            System.out.println((char) b);
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/09 16:30

    channel.position(fileSize - 1 - 1024);で末尾から取得しているのですが、出力を見ると末尾からになっていないのですが、これは何故なのでしょうか?

    キャンセル

  • 2018/09/09 19:44

    バッファの内容を全て配列に入れて先頭から1文字づつ出力しています。
    バッファの内容の出力が出来ない質問だと思いましたのでただ出力してるだけです。
    以下少し出力方法変えて100文字づつ改行した結果です。
    https://i.gyazo.com/c7b954fd391d907d62498fe982572102.png
    どちらにしてもバッファの読取りと中身がちゃんと入ってるかの確認用です。

    実際のバッファの操作は@raccyさんの回答のようにバッファ関連のメソッドを使うことをオススメします。

    キャンセル

  • 2018/09/09 20:00 編集

    a-z各100文字づつ計2600文字で実行した結果です。
    q-z各100文字x10行=1000文字+p2文字+改行22文字=1024文字になってるはずです。
    https://i.gyazo.com/fe7b8da1fc0ac2cade079b56ff9c6290.png
    https://i.gyazo.com/2d72144dfab3e2644d20b08c354f5b2b.png

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    16757questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。