在android中读取二进制文件

问题描述 投票:4回答:3

我创建了一个类型为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();
        }
    }
}

任何帮助将不胜感激。

java android fileinputstream fileoutputstream
3个回答
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())
  ;
} 

0
投票

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

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

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


0
投票

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.