将用户信息保存在文件中并获取该信息

时间:2016-06-03 11:55:13

标签: java android

我尝试了许多不同的代码,但似乎没有任何作用。

我试图创建一个简单的应用程序,可以注册用户并保存信息并使用它来登录。 我有一个名为write to file的类:

var foo = new Foo();
foo.myApiMethod(id, …);
foo.register(id).myApiMethod(…);

根据我对使用文件的理​​解,它应该没问题,但它似乎没有任何作用。

例如,如果我尝试制作一个新文件并在此处阅读:

public class WriteToFile {

Vector<Account> massAccount = new Vector<>();

public File openFile(File path, String fileName) throws IOException {
    File f = new File(path, fileName);
    f.createNewFile();
    return f;
}

public String getFileData(File f) {
    String res = "";
    res = f.getAbsolutePath() + "\n";
    res += f.length() + "\n";
    res += new java.util.Date(f.lastModified());
    return res;
}

public void writeToFile(File f, String data) throws IOException {
    FileWriter fw = new FileWriter(f);
    fw.write(data);
    fw.close();
}

public String readFromFile(File f) throws IOException {
    FileReader fr = new FileReader(f);
    int size = (int)f.length();
    char[] res = new char[size];
    fr.read(res);
    return new String(res);
}

public void writeObject(File f, String user, String pass, String question, String answer, Vector<Account> mass) throws IOException {
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
    Account acc;
    acc = new Account(user, pass,question, answer);
    out.writeObject(acc);
    for (Account accou: mass){
        out.writeObject(accou);
    }

    out.close();
}

public Object readObject(File f, String accName) throws IOException
{
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
    Account acc;
    String res = "";
    try {
        while(true)
        {
            acc = (Account) in.readObject();
            if(acc.getUsername().equals(accName))
           return acc;
        }
    }
    catch(EOFException e)
    {
        res = res + "End Of Records";
    }
    catch(ClassNotFoundException e){}
    return res;
}

public Vector<Account> readAllObjects(File f) throws  IOException{
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
    Account acc;
    String res = "";
    try{
        while(true){
            acc = (Account) in.readObject();
            massAccount.add(acc);
        }
    }
    catch (EOFException e){
        res = res + "End of Records";
    }
    catch (ClassNotFoundException e){

    }
    return massAccount;
}
}

我总是得到一个IOException,所以我猜测我的代码没问题,但我在使用文件时做错了。

非常感谢任何帮助。

由于

编辑: 我可能设法缩小问题的范围。 当我称这种方法时;

public class RegisterActivity extends AppCompatActivity {
private EditText user, pass, hint, hintans, confirm;
private Button Regi;
private String saveUser = "", savePass = "", saveHint = "", checkUser = "" , checkPass = "", saveAns = "", confirmpass = "";
private WriteToFile writeToFile;
private File f;
private Account AccInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);
    user = (EditText)findViewById(R.id.regUser);
    pass = (EditText)findViewById(R.id.regPass);
    Regi = (Button)findViewById(R.id.btncon);
    hint = (EditText)findViewById(R.id.regHint);
    hintans = (EditText)findViewById(R.id.hintAnswer);
    confirm = (EditText)findViewById(R.id.btnConPass);
    writeToFile = new WriteToFile();
    Regi.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                File dir = getFilesDir();
                f = writeToFile.openFile(dir, "User.txt");
                saveUser = user.getText().toString();
                savePass = pass.getText().toString();
                saveHint = hint.getText().toString();
                saveAns = hintans.getText().toString();
                confirmpass = confirm.getText().toString();
                AccInfo = (Account)writeToFile.readObject(f,saveUser);
                if(AccInfo.getUsername().equals(saveUser))
                    Toasty("Username already Exists.");
                if(savePass.equals(""))
                    Toasty("Cannot leave password line empty.");
                else if(!savePass.equals(confirmpass)){
                    Toasty("Passwords don't match!");
                }
                else{
                    writeToFile.readAllObjects(f);
                    writeToFile.writeObject(f, saveUser, savePass, saveHint, saveAns, writeToFile.readAllObjects(f));
                    Toasty("You have successfully registered!");
                    Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
                    startActivity(i);
                }
            }
            catch (IOException e){
                Log.d("Error", "Regi onclick");
            }
        }
    });
}

private void Toasty(String word){
    Toast.makeText(RegisterActivity.this, word, Toast.LENGTH_SHORT).show();
}

}

我明白了:

  AccInfo = (Account)writeToFile.readObject(f,saveUser);

导致:

 Regi onclick: null
 java.io.EOFException
 at libcore.io.Streams.readFully(Streams.java:83)
 at  java.io.DataInputStream.readShort(DataInputStream.java:152)
      atjava.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2061)
 at java.io.ObjectInputStream.<init>(ObjectInputStream.java:371)
 at merccorp.worklist.WriteToFile.readObject(WriteToFile.java:69)
 at merccorp.worklist.RegisterActivity$1.onClick(RegisterActivity.java:55)
 at android.view.View.performClick(View.java:5198)
 at android.view.View$PerformClick.run(View.java:21147)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5417)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

它指向第一行:

 public Object readObject(File f, String accName) throws IOException {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(f));
    Account acc;
    String res = "";
    try {
        while(true) {
            acc = (Account) in.readObject();
            if(acc.getUsername().equals(accName))
                return acc;
        }
    }
    catch(EOFException e) {
        return acc = new Account("Default","secretPass","","");
    }
    catch(ClassNotFoundException e){}
    return acc = new Account("Default","secretPass","","");
}

我不知道我做错了什么。 我很抱歉代码的数量,但我非常困惑的原因是什么。

再次感谢!

2 个答案:

答案 0 :(得分:0)

您可以使用SQLite保存用户信息。这很容易再次访问。

DataBaseHelper.java

package com.techblogon.loginexample;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DataBaseHelper extends SQLiteOpenHelper
{
    public DataBaseHelper(Context context, String name,CursorFactory factory, int version) 
    {
               super(context, name, factory, version);
    }
    // Called when no database exists in disk and the helper class needs
    // to create a new one.
    @Override
    public void onCreate(SQLiteDatabase _db) 
    {
            _db.execSQL(LoginDataBaseAdapter.DATABASE_CREATE);

    }
    // Called when there is a database version mismatch meaning that the version
    // of the database on disk needs to be upgraded to the current version.
    @Override
    public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion) 
    {
            // Log the version upgrade.
            Log.w("TaskDBAdapter", "Upgrading from version " +_oldVersion + " to " +_newVersion + ", which will destroy all old data");

            // Upgrade the existing database to conform to the new version. Multiple
            // previous versions can be handled by comparing _oldVersion and _newVersion
            // values.
            // The simplest case is to drop the old table and create a new one.
            _db.execSQL("DROP TABLE IF EXISTS " + "TEMPLATE");
            // Create a new one.
            onCreate(_db);
    }

}

LoginDataBaseAdapter.java

package com.techblogon.loginexample;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class LoginDataBaseAdapter 
{
        static final String DATABASE_NAME = "login.db";
        static final int DATABASE_VERSION = 1;
        public static final int NAME_COLUMN = 1;
        // TODO: Create public field for each column in your table.
        // SQL Statement to create a new database.
        static final String DATABASE_CREATE = "create table "+"LOGIN"+
                                     "( " +"ID"+" integer primary key autoincrement,"+ "USERNAME  text,PASSWORD text); ";
        // Variable to hold the database instance
        public  SQLiteDatabase db;
        // Context of the application using the database.
        private final Context context;
        // Database open/upgrade helper
        private DataBaseHelper dbHelper;
        public  LoginDataBaseAdapter(Context _context) 
        {
            context = _context;
            dbHelper = new DataBaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
        public  LoginDataBaseAdapter open() throws SQLException 
        {
            db = dbHelper.getWritableDatabase();
            return this;
        }
        public void close() 
        {
            db.close();
        }

        public  SQLiteDatabase getDatabaseInstance()
        {
            return db;
        }

        public void insertEntry(String userName,String password)
        {
           ContentValues newValues = new ContentValues();
            // Assign values for each row.
            newValues.put("USERNAME", userName);
            newValues.put("PASSWORD",password);

            // Insert the row into your table
            db.insert("LOGIN", null, newValues);
            ///Toast.makeText(context, "Reminder Is Successfully Saved", Toast.LENGTH_LONG).show();
        }
        public int deleteEntry(String UserName)
        {
            //String id=String.valueOf(ID);
            String where="USERNAME=?";
            int numberOFEntriesDeleted= db.delete("LOGIN", where, new String[]{UserName}) ;
           // Toast.makeText(context, "Number fo Entry Deleted Successfully : "+numberOFEntriesDeleted, Toast.LENGTH_LONG).show();
            return numberOFEntriesDeleted;
        }   
        public String getSinlgeEntry(String userName)
        {
            Cursor cursor=db.query("LOGIN", null, " USERNAME=?", new String[]{userName}, null, null, null);
            if(cursor.getCount()<1) // UserName Not Exist
            {
                cursor.close();
                return "NOT EXIST";
            }
            cursor.moveToFirst();
            String password= cursor.getString(cursor.getColumnIndex("PASSWORD"));
            cursor.close();
            return password;                
        }
        public void  updateEntry(String userName,String password)
        {
            // Define the updated row content.
            ContentValues updatedValues = new ContentValues();
            // Assign values for each row.
            updatedValues.put("USERNAME", userName);
            updatedValues.put("PASSWORD",password);

            String where="USERNAME = ?";
            db.update("LOGIN",updatedValues, where, new String[]{userName});               
        }       
}

注册

// get Instance  of Database Adapter
LoginDataBaseAdapter loginDataBaseAdapter=new LoginDataBaseAdapter(this);
loginDataBaseAdapter=loginDataBaseAdapter.open();


// Save the Data in Database
loginDataBaseAdapter.insertEntry(userName, password);

登录

// fetch the Password form database for respective user name
String storedPassword=loginDataBaseAdapter.getSinlgeEntry(userName);

// check if the Stored password matches with  Password entered by user
if(password.equals(storedPassword))
{
    //.....
}
else
{
    //...
}

答案 1 :(得分:0)

你不应该写自己的openFile(...) - 方法(也许你错误地解释了android persisntance article)。而是使用Context中的预定义方法。您的活动是Context的子类,因此您可以直接使用它。

Context con = MyActivity.this; //Activity is subclass of Context

//reading file content
FileInputStream fis = con.openFileInput("myfilename.bin");

//writing file content
int mode = Context.MODE_PRIVATE; // or Context.MODE_APPEND, see Context API
FileOutputStream fos = con.openFileOutput("myfilename.bin", mode);

//or
//alternate solution 
File currentDir = con.getFilesDir();
File newFile = new File(currentDir, "myfilename.bin");

你的代码可能很简单,看看我们已经看到了

...
Regi.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        try {
            //File dir = getFilesDir(); not this way!
            File dir = RegisterActivity.this.getFilesDir();  //but this way
            //doing it this way you use the Context in a proper way
            ...
        }...
    }
}