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

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

ただいまの
回答率

90.84%

  • Java

    12840questions

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

  • Android

    6104questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3374questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

ファイルの追記が出来ない

解決済

回答 1

投稿 編集

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

Wind

score 167

問題

サンプル1サンプル2を元に、テキストファイルへ追記し続けるサンプルを作成してみたのですが、ファイルの新規作成のみで追記されません。
ファイルが存在すると変更されず、一度ファイルを削除すると新規に項目が一つ保存されたファイルが作成されます。

(例)ボタンを3回押してから"testfile.txt"を削除して、ボタンを押すと”testfile.txt"が作成されて中身は「test3」だけが保存される。
この後にボタンを押しても中身は変わらない。

FileOutputStream fos = new FileOutputStream(file,true);     // 追記
だけでは追記されないのでしょうか?

環境

開発環境:AndroidStudio 3.0.1
実機:Android 6.0

やりたいこと

ファイルの追記が出来る様にしたいです。

ソースコード

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    public static void verifyStoragePermissions(Activity activity) {
        int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);

        if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }

    // メディアスキャン
    final MediaScannerConnection.OnScanCompletedListener mScanCompletedListner = new MediaScannerConnection.OnScanCompletedListener()
    {
        @Override
        public void onScanCompleted(String path, Uri uri)
        {
        }
    };

    private TextView textView;
    private String fileName = "testfile.txt";
    private int intRaw = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        verifyStoragePermissions(this);

        textView = findViewById(R.id.text_view);

        Button buttonSave = findViewById(R.id.button_save);
        buttonSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String strFileName = Environment.getExternalStorageDirectory().getPath() + "/" + fileName;  // 内部ストレージ直下
                String text = "test" + intRaw;      // 保存する内容

                saveFile(strFileName, text);
                if(text.length() == 0){
                    textView.setText(R.string.no_text);
                }
                else{
                    textView.setText(R.string.saved);
                }

                String[] paths = {strFileName};
                MediaScannerConnection.scanFile(getApplicationContext(), paths, null, mScanCompletedListner);

                intRaw++;
            }
        });
    }

    // ファイルを保存
    public void saveFile(String file, String str) {
        try {
            FileOutputStream fos = new FileOutputStream(file,true);     // 追記
            OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);
            bw.write(str);
            bw.newLine();       // 改行
            bw.flush();
            bw.close();
            Log.i("MainActivity","Saved:" + str);
        } catch (FileNotFoundException e) {
            Log.d("MainActivity", e.toString());
        } catch (IOException e) {
            Log.d("MainActivity", e.toString());
        }
    }
}

テスト結果の追記

確認方法に「USB接続しているWindowsPCでファイルを見ている」ことを記述していませんでした。

出力ファイルをWindowsPCで確認したところ、
・スマホを再起動すれば「testfile.txt」の中身は反映される。
・但しnewLine()(改行)は適用されていない

MediaScannerConnection.scanFile()だけでは中身までWindows PCで見れる様にならないのでしょうか?
もしくは使い方が間違っているのでしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • 退会済みユーザー

    退会済みユーザー

    2018/04/26 19:00

    私の環境でsaveFile()だけテストしたらうまくいきました。2回目以降、saveFile()が呼ばれていないとか、呼ばれているけど例外が発生しているということはありませんか?

    キャンセル

  • Wind

    2018/04/26 22:28

    確認ありがとうございます。saveFile()でLog.iでカウントアップ出来てるので呼ばれてはいるのは確認しました。例外が出ればどちらかのLog.dにひっかかるかと思ったのですが発生しないので、追記出来ない原因が不明です。ウイルス対策ソフトも入っていませんし・・・。

    キャンセル

  • asahina1979

    2018/04/27 08:26

    内容を確認の方はエディタを完全に落としてないんだろうけど

    キャンセル

  • Wind

    2018/04/27 10:02

    確認の方はメモ帳で行っていて毎回終了しています。ただスマホを再起動してからファイルを開いたところ、改行はされていませんが連続で保存されていたので、newLine()が1回も動かずメディアスキャンが1回しか動いていないぽい感じでした。

    キャンセル

回答 1

checkベストアンサー

+1

改行はされていませんが連続で保存されていたので

メモ帳で開いたら

test0test1test2


と表示されたということでしょうか?もしそうだとしたら、改行コードの問題ですね。

伝統的に、Windows、macOS、UNIX系のそれぞれのOSでは、テキストファイルにおいて改行を表現するコードに違いがあります。詳細についてはここで細かく説明するよりも、

改行コード - Wikipedia

などをご参照いただくのが良いかと思います。

Androidアプリにおいて、newline()メソッドによって出力される改行コードの処理は、UNIX系の「LFのみ」に準じます。ところが、Windowsのメモ帳はWindows方式の「CR+LF」しか正しく改行として表示されないので、全てのテキストが繋がって見えているだけなのでしょう。プログラムとしては正常に機能していると思われます。

メモ帳ではなく、別のテキストエディターを用いた方が良いでしょう。ワードパッドでもLFのみのファイルを正しく表示できたんじゃなかったかな?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/29 20:51

    コメントありがとうございます。
    メモ帳で開くと最初は
    test0
    と表示され、スマホを再起動すると
    test0test1test2
    と、表示されます。

    確かにWindowsPCで確認する時は「CR+LR」が見えるエディタが良いですね。
    ちょっと探してみます。

    キャンセル

  • 2018/05/07 12:12

    追記毎にメディアスキャンをすることは出来ないのですね。
    追記終了後に一括でメディアスキャンをすることで動きました。
    ありがとうございました。

    キャンセル

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

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

関連した質問

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

  • Java

    12840questions

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

  • Android

    6104questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3374questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。