在android中读取二进制文件

时间:2014-02-16 20:22:32

标签: java android fileinputstream fileoutputstream

我创建了一个Task类型的自定义对象,我想将其保存在内部存储中的二进制文件中。这是我创建的课程:

public class Task{

private String title;
private int year;
private int month;
private int day;
private int hour;
private int minute;

public Task(String inputTitle, int inputYear, int inputMonth, int inputDay, int inputHour, int inputMinute){

    this.title = inputTitle;
    this.year = inputYear;
    this.month = inputMonth;
    this.day = inputDay;
    this.hour = inputHour;
    this.minute = inputMinute;

}

public String getTitle(){

    return this.title;

}

public int getYear(){

    return this.year;

}

public int getMonth(){

    return this.month;

}

public int getDay(){

    return this.day;

}

public int getHour(){

    return this.hour;

}

public int getMinute(){

    return this.minute;

}
}

在一个活动中,我创建了一个将对象保存到文件的方法。这是我使用的代码:

public void writeData(Task newTask){

        try {

            FileOutputStream fOut = openFileOutput("data",MODE_WORLD_READABLE);
            fOut.write(newTask.getTitle().getBytes());
            fOut.write(newTask.getYear());
            fOut.write(newTask.getMonth());
            fOut.write(newTask.getDay());
            fOut.write(newTask.getHour());
            fOut.write(newTask.getMinute());
            fOut.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e){

            e.printStackTrace();

        }
}

现在我想创建一个从文件中提取数据的方法。通过在互联网上阅读,很多人使用FileInputStream,但是我无法从中提取字节并知道字符串可以有多长。此外,我使用了一种在线发现的简单方法,但我得到了许可被拒绝。正如我所说,我对Android开发非常陌生。

public void readData(){

    FileInputStream fis = null;

    try {
        fis = new FileInputStream("data");

        System.out.println("Total file size to read (in bytes) : "
                + fis.available());

        int content;
        while ((content = fis.read()) != -1) {
            // convert to char and display it
            System.out.print((char) content);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null)
                fis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:8)

对于权限问题,我建议您使用外部存储设备,例如SD卡。

Environment.getExternalStorageDirectory()

您可以在那里创建一个文件夹并保存文件。如果系统允许将用户文件保存在那里,也可以使用“/ data / local /”。 关于将文件保存到内部和外部存储的各种方法,您可以参考此page

对于第二个问题,我建议您使用DataInputStream

File file = new File("myFile");
byte[] fileData = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(fileData);
dis.close();

你可以编写类似这样的代码,

import java.io.*;
public class Sequence {
    public static void main(String[] args) throws IOException {
    DataInputStream dis = new DataInputStream(System.in);
    String str="Enter your Age :";
    System.out.print(str);
    int i=dis.readInt();
    System.out.println((int)i);
    }
}

您还可以使用Serializable界面来读取和编写可序列化对象。事实上,当我尝试将数据值直接写入文件而不是任何传统数据库时,我曾经使用过一次(在我的第一个大学本科,我不熟悉数据库)。一个很好的例子是here

import java.io.*;
import java.util.*;
import java.util.logging.*;

/** JDK before version 7. */
public class ExerciseSerializable {

  public static void main(String... aArguments) {
    //create a Serializable List
    List<String> quarks = Arrays.asList(
      "up", "down", "strange", "charm", "top", "bottom"
    );

    //serialize the List
    //note the use of abstract base class references

    try{
      //use buffering
      OutputStream file = new FileOutputStream("quarks.ser");
      OutputStream buffer = new BufferedOutputStream(file);
      ObjectOutput output = new ObjectOutputStream(buffer);
      try{
        output.writeObject(quarks);
      }
      finally{
        output.close();
      }
    }  
    catch(IOException ex){
      fLogger.log(Level.SEVERE, "Cannot perform output.", ex);
    }

    //deserialize the quarks.ser file
    //note the use of abstract base class references

    try{
      //use buffering
      InputStream file = new FileInputStream("quarks.ser");
      InputStream buffer = new BufferedInputStream(file);
      ObjectInput input = new ObjectInputStream (buffer);
      try{
        //deserialize the List
        List<String> recoveredQuarks = (List<String>)input.readObject();
        //display its data
        for(String quark: recoveredQuarks){
          System.out.println("Recovered Quark: " + quark);
        }
      }
      finally{
        input.close();
      }
    }
    catch(ClassNotFoundException ex){
      fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
    }
    catch(IOException ex){
      fLogger.log(Level.SEVERE, "Cannot perform input.", ex);
    }
  }

  // PRIVATE 

  //Use Java's logging facilities to record exceptions.
  //The behavior of the logger can be configured through a
  //text file, or programmatically through the logging API.
  private static final Logger fLogger =
    Logger.getLogger(ExerciseSerializable.class.getPackage().getName())
  ;
} 

答案 1 :(得分:0)

从我看到的,您正在尝试将对象的内容转储到文件中,然后将其读回。但是你现在这样做的方法就是将所有数据写入文件而不需要任何结构,这是一个糟糕的主意。

我建议您尝试实现Serializable interface,然后使用writeObject()和readObject()方法。

或者,您可以将数据转储到XML文件或具有某种结构的文件中。

答案 2 :(得分:0)

Android为每种应用程序提供了一种私有目录结构,以实现这种数据。您无需特殊权限即可访问它。唯一的警告(通常是一个很好的警告)是只有你的应用可以访问它。 (这个原则是安全性的一部分,可以防止其他应用程序对您做坏事。)

如果这符合您的存储需求,只需从任何可用的上下文(通常是您的活动)中调用getFilesDir()即可。在您的情况下,您可能希望将上下文作为readData()writeData()的参数传递。或者您可以致电getFilesDir()获取存储目录,然后将其作为参数传递给readData()writeData()

另一个警告(艰难地学习)。虽然没有文档,但我发现有时Android会在这个应用程序目录中创建文件。我强烈建议您不要直接在此应用程序文件夹中存储文件,而是在getFilesDir()返回的应用程序目录中创建自己的存储目录,然后将文件存储在那里。这样您就不必担心可能出现的其他文件,例如,如果您尝试列出存储目录中的文件。

File myStorageFolder = new File(context.getFilesDir(), "myStorageFolder");

(我同意P basak DataInputStreamDataOutputStream是您阅读和编写数据的最佳选择。我不推荐序列化,除非在一个非常狭窄的应用程序中,可移植性是一个因素,因为它是非常低效的。在我的情况下,使用DataInputStream在不到2秒的时间内通过序列化加载需要15秒加载的对象。)