我尝试了许多不同的代码,但似乎没有任何作用。
我试图创建一个简单的应用程序,可以注册用户并保存信息并使用它来登录。 我有一个名为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","","");
}
我不知道我做错了什么。 我很抱歉代码的数量,但我非常困惑的原因是什么。
再次感谢!
答案 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
...
}...
}
}