My Goal is to be able to save as many high scores from my application to my text file i create using FileOutputStream. I then want to be able to read from the file and put each line into an array list item. While using InputStreamReader I am able to load all of the lines of text from the text file into the variable s. My problem now is i want to take each line from the text file and save it into an array list item. How would i accomplish this?
Example string variables for high scores:
String myStr = "Ryan 150 hard \n";
String myStr2 = "Andrew 200 Medium \n";
public void saveClick(){
try{
//String myNum = Integer.toString(life);
FileOutputStream fOut = openFileOutput("storetext.txt", Context.MODE_PRIVATE);
OutputStreamWriter outputWriter = new OutputStreamWriter(fOut);
outputWriter.write(myStr);
outputWriter.write(myStr2);
outputWriter.close();
/*OutputStreamWriter out = new OutputStreamWriter(openFileOutput(STORETEXT, 0));
out.write(life);
out.close();*/
Toast.makeText(getApplicationContext(), "Save Successful", Toast.LENGTH_LONG).show();
}
catch(Throwable t){
Toast.makeText(getApplicationContext(), "Save Unsuccessful", Toast.LENGTH_LONG).show();
}
}
public void readFileInEditor(){
try{
FileInputStream fileIn = openFileInput("storetext.txt");
InputStreamReader InputRead = new InputStreamReader(fileIn);
char [] inputBuffer = new char[READ_BLOCK_SIZE];
String s = "";
int charRead;
while ((charRead=InputRead.read(inputBuffer))>0){
//char to string conversion
String readString = String.copyValueOf(inputBuffer,0,charRead);
s += readString;
}
InputRead.close();
Toast.makeText(getApplicationContext(), "New Text: " + s , Toast.LENGTH_LONG).show();
//myText.setText("" + s);
try{
//life = Integer.parseInt(s);
//Toast.makeText(getApplicationContext(), "My Num: " + life , Toast.LENGTH_LONG).show();
}
catch(NumberFormatException e){
//Toast.makeText(getApplicationContext(), "Could not get number" + life , Toast.LENGTH_LONG).show();
}
}
catch(java.io.FileNotFoundException e){
//have not created it yet
}
catch(Throwable t){
Toast.makeText(getApplicationContext(), "Exception: "+t.toString(), Toast.LENGTH_LONG).show();
}
}
To make your life easier, better to use (1) BufferedReader::readline() method, or (2) Scanner::nextLine() method. And add each line to a List<String> in the for loop.
A simple example:
List<String> lines = new ArrayList<>();
String curLine = null;
BufferedReader reader = new BufferedReader(new FileReader("storetext.txt"));
while ((curLine = reader.readLine()) != null) {
lines.add(curLine);
}
Use BufferedReader to read line by line and put them in an ArrayList right away.
Related
I Want to Make A System that compares password (4 letter numeric).
Input Code (I Already Have fis)
fis = openFileInput(FILE_NAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String text;
while((text = br.readLine()) != null)
{
sb.append(text).append("\n");
}
String finalinput = sb.toString();
String finalpassinput = password.getText().toString();
Toast.makeText(this, "finalinput:"+finalinput+"finalpassinput:"+finalpassinput,Toast.LENGTH_LONG).show();
if(finalinput.equals(finalpassinput))
{
Toast.makeText(this,"Login!", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this, HomeActivity.class));
}
else
{
Toast.makeText(this,"Incorrect Password",Toast.LENGTH_SHORT).show();
}
And This Source Code will keep say that the two passwords are different.
How I Wrote My File :
fos = openFileOutput(FILE_NAME_PW, MODE_PRIVATE);
fos.write(encodedpw.getBytes());
Toast.makeText(this, "Saved to " + getFilesDir() + "/" + FILE_NAME_PW, Toast.LENGTH_LONG).show();
I am curious if encodepw.getBytes() will change anything to the string (Including null characters, etc.) and if Java won't think them the same.
Thank you.
I found myself the answer to it. The finalinput variable had some null charachter before it, so you can get pure string using this function.
public static String FileStringParse(String FileString)
{
FileString = FileString.replaceAll("\\D+","");
return FileString;
}
I'm using internal storage to store multiple strings entered by the user through multiples edit text.
So the layout is composed of multiples Textviews which correspond to the title of the fields, and multiples Edittexts which correspond to the fields where the user can enter his string.
When the user has finished, he presses the save button and this function is triggered :
public void save(View view) // SAVE
{
File file= null;
String name = editname.getText().toString()+"\n";
String marque = editmarque.getText().toString()+"\n";
String longueur = editlongueur.getText().toString()+"\n";
String largeur = editlargeur.getText().toString()+"\n";
String tirant = edittirant.getText().toString()+"\n";
String immatri = editImmatriculation.getText().toString()+"\n";
String port = editPort.getText().toString()+"\n";
String contact = editContact.getText().toString()+"\n";
String panne = editPanne.getText().toString()+"\n";
String poste = editPoste.getText().toString()+"\n";
String police = editPolice.getText().toString()+"\n";
String assurance = editAssurance.getText().toString();
FileOutputStream fileOutputStream = null;
try {
file = getFilesDir();
fileOutputStream = openFileOutput("Code.txt", Context.MODE_PRIVATE); //MODE PRIVATE
fileOutputStream.write(name.getBytes());
fileOutputStream.write(marque.getBytes());
fileOutputStream.write(longueur.getBytes());
fileOutputStream.write(largeur.getBytes());
fileOutputStream.write(tirant.getBytes());
fileOutputStream.write(immatri.getBytes());
fileOutputStream.write(port.getBytes());
fileOutputStream.write(contact.getBytes());
fileOutputStream.write(panne.getBytes());
fileOutputStream.write(poste.getBytes());
fileOutputStream.write(police.getBytes());
fileOutputStream.write(assurance.getBytes());
Toast.makeText(this, "Saved \n" + "Path --" + file + "\tCode.txt", Toast.LENGTH_SHORT).show();
editname.setText("");
editmarque.setText("");
editlargeur.setText("");
editlongueur.setText("");
edittirant.setText("");
editImmatriculation.setText("");
editPort.setText("");
editContact.setText("");
editPanne.setText("");
editPoste.setText("");
editPolice.setText("");
editAssurance.setText("");
return;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Than, in another file I retrieve this data through another button that triggers this function :
public void load(View view)
{
try {
FileInputStream fileInputStream = openFileInput("Code.txt");
int read = -1;
StringBuffer buffer = new StringBuffer();
while((read =fileInputStream.read())!= -1){
buffer.append((char)read);
}
fileInputStream.close();
String tab[] = buffer.toString().split("\n");
String boatname = tab[0];
String marque = tab[1];
String longueur = tab[2];
String largeur = tab[3];
String tirant = tab[4];
String immatri = tab[5];
String port = tab[6];
String contact = tab[7];
String panne = tab[8];
String poste = tab[9];
String assurance = tab[10];
String police = tab[11];
getboatname.setText(boatname);
getmarque.setText(marque);
getlongueur.setText(longueur);
getlargeur.setText(largeur);
getTirantdeau.setText(tirant);
getImmatriculation.setText(immatri);
getPort.setText(port);
getContact.setText(contact);
getPanne.setText(panne);
getPoste.setText(poste);
getAssurance.setText(assurance);
getPolice.setText(police);
} catch (Exception e) {
e.printStackTrace();
}
}
So in the save function I'm splitting the entered strings with \n, and I save the file to the internal storage, and in the load function I retrieve the strings using an array and splitting with every \n and I set the text with the correct index.
What I don't understand is that the results are all mixed up, the string of the first field is displayed in the last field for example, why ?
You can Make a Single String and write it. Also, use a different separator. You can use StringBuffer for it.
StringBuffer s=new StringBuffer();
s.append(editname.getText().toString());
s.append("##########");
s.append(editmarque.getText().toString());
s.append("##########");
s.append(editlongueur.getText().toString());
s.append("##########");
s.append(editlargeur.getText().toString());
s.append("##########");
s.append(edittirant.getText().toString());
s.append("##########");
s.append(editPort.getText().toString());
s.append("##########");
s.append(editContact.getText().toString());
s.append("##########");
s.append(editPanne.getText().toString());
s.append("##########");
s.append(editPoste.getText().toString());
s.append("##########");
s.append(editPolice.getText().toString());
s.append("##########");
s.append(editAssurance.getText().toString());
s.append("##########");
FileOutputStream fileOutputStream = null;
try {
file = getFilesDir();
fileOutputStream = openFileOutput("Code.txt", Context.MODE_PRIVATE); //MODE PRIVATE
fileOutputStream.write(s.toString().getBytes());
Toast.makeText(this, "Saved \n" + "Path --" + file + "\tCode.txt", Toast.LENGTH_SHORT).show();
editname.setText("");
editmarque.setText("");
editlargeur.setText("");
editlongueur.setText("");
edittirant.setText("");
editImmatriculation.setText("");
editPort.setText("");
editContact.setText("");
editPanne.setText("");
editPoste.setText("");
editPolice.setText("");
editAssurance.setText("");
return;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
When you get FileInputStream split the String with this "##########" vlaue
InputStream is = getResources().openRawResource(R.raw.babynames);
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, Charset.forName("UTF-8"))
);
String line = "";
try {
reader.readLine();
while ((line = reader.readLine()) != null) {
Log.d("MyActivity", "Line: " + line);
String[] tokens = line.split(",");
BabyName name = new BabyName();
name.setGender(tokens[1]);
name.setMeaning(tokens[2]);
name.setName(tokens[3]);
name.setOrigin(tokens[4]);
babyNames.add(name);
Log.d(TAG, "Just created: " + name);
}
} catch (IOException e) {
Log.wtf("MyActivity", "Error reading data file on line" + line, e);
e.printStackTrace();
}
i am trying this but the app crashes and I got an error of array index out of bound and in logs i am getting the data
BabyName name = new BabyName();
name.setGender(tokens[1]);
name.setMeaning(tokens[2]);
name.setName(tokens[3]);
name.setOrigin(tokens[4]);
shouldn't the index start from 0
name.setGender(tokens[0]);
I have created an ArrayList. I read text file from Android phone and store String[3] in each array. I used the debugger to trace the value of each variable. The value in ArrayList seem like always follow the value of buffer. Is it any link between them?
ArrayList<String[]> label_list = new ArrayList<>();
try {
FileInputStream fIn = new FileInputStream(getPath());
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
String[] buffer = new String[3];
int j=0;
while ((aDataRow = myReader.readLine()) != null) {
if(!aDataRow.equals("")){
buffer[j]=aDataRow;
j++;
}else{
label_list.add(buffer);
j=0;
}
}
label_list.add(buffer); //for last one
myReader.close();
for(int i=0;i<label_list.size();i++){
txt_show.append(label_list.get(i)[0]);
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
The text file i read.
The result of debugger. As you can see, all arrays have same value. The value in Arraylist will always follow the value of buffer.
You must put that j++ out of if else condition.
ArrayList<String[]> label_list = new ArrayList<>();
try {
FileInputStream fIn = new FileInputStream(getPath());
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
String[] buffer = new String[3];
int j=0;
while ((aDataRow = myReader.readLine()) != null) {
if(!aDataRow.equals("")){
buffer[j]=aDataRow;
}else{
label_list.add(buffer);
}
j++;
}
label_list.add(buffer); //for last one
myReader.close();
for(int i=0;i<label_list.size();i++){
txt_show.append(label_list.get(i)[0]);
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
hope it helps
I found my mistake. Add buffer = new String[3]; will solve my problem but I do not know why. Can anyone explain to me?
try {
FileInputStream fIn = new FileInputStream(getPath());
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
String[] buffer = new String[3];
int j=0;
while ((aDataRow = myReader.readLine()) != null) {
if(!aDataRow.equals("")){
buffer[j]=aDataRow;
j++;
}else{
label_list.add(buffer);
j=0;
**buffer = new String[3];**
}
}
myReader.close();
for(int i=0;i<label_list.size();i++){
txt_show.append(label_list.get(i)[0]);
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
I have to understand this code to create my own app(almost based on this function):
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0;
String ligne;
int j = 0;
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
s[0][j] = ligne;
else {
s[1][j] = ligne;
j++;
}
i++;
}
fIn.close();
ipsr.close();
return s;
}
catch (Exception e)
{}
I'm not understanding why the using of a 2D array? and with two rows ?(String[][] s = new String[2][i/2];)
here is the data that it will be stored in the file:
data = date + " : " + y + "L/100KM"+ " " + value1 + "L "+ value2 + "KM\n";
Necessary functions:
public void updatelv(Activity activity) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String fileName = getResources().getString(R.string.fileName);
fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";
s = myIO.ReadFilePerLine(getApplicationContext(), fileDir+fileName);
ListView L = (ListView) findViewById(R.id.lv);
L.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, s[0]));
for (int i = 0; i< s[0].length; i++) {
Log.d("Saves",s[0][i]);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.histo);
context = getApplicationContext();
activity = this;
final SharedPreferences preferences = PreferenceManager
.getDefaultSharedPreferences(context);
String fileName = getResources().getString(R.string.fileName);
fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";
s = myIO.ReadFilePerLine(getApplicationContext(), fileDir + fileName);
updatelv(this);
ListView L = (ListView) findViewById(R.id.lv);
L.setTextFilterEnabled(true);
L.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
String tmp = s[1][position];
if (tmp == null)
tmp = "Aucun fichier trouvé!";
Toast.makeText(getApplicationContext(), tmp, Toast.LENGTH_SHORT)
.show();
}
});
ReadFilePerLine function:
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0;
String ligne;
int j = 0;
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
s[0][j] = ligne;
else {
s[1][j] = ligne;
j++;
}
i++;
}
fIn.close();
ipsr.close();
return s;
}
catch (Exception e)
{
}
Thank you for you help.
The code is clearly reading from a file whose format consists of pairs of lines; it puts the first line of each pair in s[0][...] and the second line of each pair in s[1][...]. If your format doesn't have that peculiarity -- which it doesn't sound as if it does -- then you don't need to do that. Just make an ordinary 1-dimensional array of Strings.
It appears that what they are doing is breaking the file down into two lists (or String arrays, in this case), one which contains all the even-numbered lines, and one which contains all the odd-numbered lines. I'll comment up the code for you:
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
//open the specified input file and create a reader
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
//get the total number of lines in the file, and allocate
//a buffer large enough to hold them all
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0; //set the current line to 0
String ligne;
int j = 0; //set the section index to 0
//now read through the lines in the file, and place every
//even-numbered line in the first section ('s[0]'), and every
//odd-numbered line in the second section ('s[1]')
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
//even-numbered line, it goes into the first section
s[0][j] = ligne;
else {
//odd-numbered line, it goes into the second section
s[1][j] = ligne;
j++; //increment the section index
}
i++; //increment the line count
}
//done, cleanup and return
fIn.close();
ipsr.close();
return s;
}
catch (Exception e) {
//should at least log an error here...
}
}
As to why they chose to use a String[][], I cannot say. Probably for convenience, since they want a single object that they can return from this function that contains both lists. Personally I would use a Map that has two List instances in it, but the String[][] works just as well and is probably marginally more efficient.
Judging from your example data it does not appear that you need to use this format. But if you want to use it, you need to structure your data so that the key is on one line, and its associated value is on the next, like:
date
2011-03-19
userName
someGuy
it seems to read from a file, split it into the two dimensional array (based on row count).
Why it does it? I have no idea why you'd want that. Check out the function that it returns s to and find out!