Text in Datei speichern und nur auslesen, wenn Datei mit Inhalt existiert.

  • 7 Antworten
  • Letztes Antwortdatum
K

Klawifiantix

Neues Mitglied
0
Hallo zusammen,
ich bin erst seit ein paar Tagen dabei mir Java Grundkenntnisse anzueignen, da ich gerne eine eigene Android App mit Android Studio basteln möchte. Winzige Teilerfolge konnte ich schon erlangen. Für die meisten hier wird es ein Witz sein, aber da ich über keine Vorkenntnisse verfüge, erkenne ich Fortschritte.

Ich möchte vorerst eine ganz simple App erstellen. Dabei möchte ich einen Text schreiben und diesen in ein ViewText Feld übertragen. Soweit habe ich das schon mal hinbekommen. Nun möchte ich den Text auch noch abspeichern, so dass ich ihn sehe, wenn ich die App schließe und erneut starte. Das funktioniert auch. Mein Problem ist nur, dass wenn ich Speicher, obwohl kein Text existiert, zwar eine Datei erstellt wird, allerdings (so nehme ich an) diese keinen Inhalt hat. Wenn ich dann die App erneut starte, hängt diese sich auf. Ich habe versucht mit file.exist() zu arbeiten, aber das will nicht so recht klappen. Hat hier jemand eine Idee?
Prügelt mich bitte nicht, wenn die Antwort hier schon im Forum steht. Ich bin leider noch nicht auf dem Stand mir alles zusammen zu schustern.

Code:
//Über einen Button kann ich Text in einer .txt Datei hiermit speichern.
public void textSpeichern(View view) {
        try {
            String data = tv.getText().toString();
            fos = openFileOutput(geschriebenes, Context.MODE_PRIVATE);
            fos.write(data.getBytes());
            fos.close();
        }   catch (FileNotFoundException e) {
            e.printStackTrace();
        }   catch (IOException e) {
            e.printStackTrace();
        }
    }

//Das soll der Befehl sein, um die Datei auszulesen, wenn sie existiert. 
File f = new File(geschriebenes);
        if (f.exists()) {
            try {
                fis = openFileInput(geschriebenes);
                byte[] readData = new byte [fis.available()];
                while (fis.read(readData) != -1){
                    collected = new String(readData);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            tv.setText(collected);

Hier mal der komplette Code, da ich noch nicht weiß, was man wissen muss, um mir helfen zu können:

Code:
package de.diz.versuch;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Path;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Writer;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Date;

import static de.diz.versuch.R.string;

public class MainActivity extends Activity  {

    public TextView tv; //Das Textfeld, in dem der Text abschließend stehen soll.
    public TextView da; //Das Textfeld, in dem das Datum angezeigt wird.
    public EditText et; //Das Textfeld, in das geschrieben wird.
    public Button btn2; //Der Button zum Bearbeiten.
    public SimpleDateFormat Datum = new SimpleDateFormat("HH:mm - dd.MM.yyyy"); //Definieren des Formats, mit dem das Datum angezeigt werden soll.
    public FileOutputStream fos;
    public FileInputStream fis;
    public String geschriebenes = "test.txt";
    public String collected;

    //Die Hauptfunktion. hier definiere ich die Variablen.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        tv = (TextView)findViewById(R.id.Text);
        tv.setMovementMethod(new ScrollingMovementMethod());
        et = (EditText)findViewById(R.id.eingabe);
        da = (TextView)findViewById(R.id.datum);
        btn2 = (Button)findViewById(R.id.btn2Klick);
        btn2.setVisibility(View.GONE);

        File f = new File(geschriebenes);
        if (f.exists()) {
            try {
                fis = openFileInput(geschriebenes);
                byte[] readData = new byte [fis.available()];
                while (fis.read(readData) != -1){
                    collected = new String(readData);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            tv.setText(collected);
        }






    if(tv.getText().toString().equals("")) {
        btn2.setVisibility(View.GONE);
    }else {
        btn2.setVisibility(View.VISIBLE);
    }
        }




    //Diese Funktion/en wird/werden ausgeführt, wenn der Button "Eingabe" benutzt wird.
    public void displayEditText(View view) {
        //Hier wird das Datum gesetzt
        if (et.getText().toString().equals("")){

        }else {
            if(da.getText().toString().equals("")){
                Date currentTime = new Date();
                da.setText(Datum.format(currentTime));
            }
        }
        //Hier wird der Text aus dem EditText Feld in das ViewText Feld übertragen.
        if (tv.getText().toString().equals("")&(et.getText().toString().equals(""))){

        }else {
            if(tv.getText().toString().equals("")){
                String editTextValue = (et.getText().toString());
                tv.setText(editTextValue);
                et.setText("");
                btn2.setVisibility(View.VISIBLE);
            }
        }
        //Hier wird Text aus dem EditText Feld dem ViewText Feld hinzugefügt.
        if (et.getText().toString().equals("")){

        }else{
            String editTextValue = (tv.getText().toString()) + ('\n') + (et.getText().toString());
            tv.setText(editTextValue);
            et.setText("");
        }
    }
    //Diese Funktion läuft, wenn der Button "Bearbeiten" gedrückt wird.
    public void textBearbeiten(View view) {
        //Hier wird Text von dem ViewText Feld in das EditText Feld übertragen. Und der Text im ViewText Feld gelöscht.
    if (tv.getText().toString().equals("")){

    }else{
        et.setText(tv.getText().toString());
        tv.setText("");
        btn2.setVisibility(View.GONE);
    }
    }

    public void textSpeichern(View view) {
        try {
            String data = tv.getText().toString();
            fos = openFileOutput(geschriebenes, Context.MODE_PRIVATE);
            fos.write(data.getBytes());
            fos.close();
        }   catch (FileNotFoundException e) {
            e.printStackTrace();
        }   catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

Lieben Dank im Voraus!
 
Habe mir jetzt nicht deinen Code angeschaut, aber 2 Sachen:

1. Es gibt LogCat. Das ist ein Log Progrann und zeigt dir deine Fehler an, wenn die App abstürtzt. Dies ist schon im AndroidStudio enthalten und wird dir angezeigt! Diesen bitte Posten1

2. Wenn du nicht willst, dass eine leeres Textfile erstellt wird, kannst du VOR dem Speichern sagen:
Code:
public void textSpeichern(View view) {
  if(view.getText().toString().equals("")) {
    // Nicht Speicher, da leerer Inhalt
  } else {
    // Speichern!
   }
}

Gruß
 
Du kannst auch eine leere Datei schreiben, das ist ja nicht das Problem. Aber ich denke, das Problem ist bei der Initialisierung des strings:
Code:
collected = new String(readData);

Das macht du nämlich nur, wenn du aus der Datei was lesen konntest. Ich sehe aber in deinem Code-Snippet nicht, ob du collected vorher initialisiert hast oder obs auf NULL steht. Vielleicht ist das dein Problem.

Im LogCat müßte man aber sehen, wo es knallt.

Edit: Achja, du hast ja den ganzen Code nochmal gepostet ... ja collected ist null ... außerdem erzeugst du in der while schleife immer ein new string und setzt collected quasi auf den letzten gelesenen string. wenn dein textview mehrzeilig ist, müßte da eher sowas stehen wie collected = collected + new String(readData) oder gleich nen StringBuffer nutzen und .append()
 
Zuletzt bearbeitet:
Vorab lieben Dank für die schnellen Antworten, ich denke, die haben mich schon ein Stück weiter gebracht.
Ich suche momentan eine Möglichkeit abzufragen, ob eine bestimmte Datei existiert. Da gibt es wohl Code wie:

Code:
String geschriebenes = "text.txt"

File f = new File(geschriebenes)
if(f.exists()) {
//mach was
}

Falls die Datei existiert, soll sie ausgelesen und der Inhalt in einem Textfeld angezeigt werden. Falls nicht, soll das Textfeld leer bleiben. Mit dem angeführten Code funktioniert es nicht und ich finde den Fehler nicht. Wahrscheinlich weil ich nicht weiß, ob das überhaupt der richtige Weg ist :-/ Und wenn die Datei existiert, aber leer ist, würde es dann Probleme bereiten? Ich meine dann wird überprüft ob die Datei existiert, dann ist sie aber leer und es wird trotzdem versucht sie auszulesen, was ja nicht klappen kann... oder wie funktioniert das?

Lieben Gruß
Klaw
 
Wenn sie leer ist kannst du sie trotzdem auslesen, nur wird der Inhalt dann ein leerer String sein oder null.
Aber was genau ist denn dein Problem?
 
Was das eigentliche Problem war, kann ich mittlerweile nicht mehr ganz nachvollziehen :ohmy: Aber bis jetzt funktioniert alles.
Jetzt brauche ich eine Lösung um ein TextView Feld automatisch an dessen ende zu scrollen. Dazu versuche ich die Zeilenanzahl des Textes herauszufinden. aber
Code:
.getLineCount()
funktioniert noch nicht. Da muss das Layout wohl erst für gerendert sein. Keine Ahnung, bis jetzt, was damit gemeint ist^^

Der ursprüngliche Beitrag von 22:10 Uhr wurde um 22:11 Uhr ergänzt:

Hiermit, habe ich meine "gibt es die Datei - Abfrage" hinbekommen:
Code:
File file = getBaseContext().getFileStreamPath(geschriebenes);
        if (file.exists()) {
            try {//Hier wird die Datei Tagebuch.txt geladen und angezeigt.
                fis = openFileInput(geschriebenes);
                byte[] readData = new byte [fis.available()];
                while (fis.read(readData) != -1){
                    collected = new String(readData);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tv.setText(collected);
                counterA = 1;

                    }
                }
 
Dein Datei auslesen klappt aber nicht mehr wenn deine Datei zu groß ist.
fis.available() gibt nämlich nicht zwingend die größe der ganzen datei zurück.

Und dann hast du am Ende nur das in deinem collected, was als letztes gelesen wurde.

Ausserdem solltest du den fileInputStream buffern.
z.B.
BufferedReader | Android Developers
Gleichzeitig hast du dann einen Reader, der dir schon chars zurück gibt und du nicht mit den nackten Bytes arbeitest.

Oder guck dir an wie's hier gemacht wird:
android - Read file As String - Stack Overflow
 
Das wusste ich natürlich nicht. Vielen Dank für den Hinweis. Ich bin jetzt erstmal fern der Heimat, aber bei meiner Rückkehr werde ich versuchen Deinen Rat bestmöglich zu befolgen. Hast Du auch eine Idee, wie ich das TextView Feld immer automatisch ganz nach unten scrollen kann?
 
Zurück
Oben Unten