簡體   English   中英

在Android中寫入和讀取二進制文件

[英]Write and read binary files in Android

我創建了一個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但我無法從中提取字節並知道String可以有多長。 此外,我使用了一種在線發現的簡單方法,但我得到了許可被拒絕。 正如我所說,我對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();
        }
    }
}

任何幫助將不勝感激。

對於權限問題,我建議您使用外部存儲設備,如SD卡。

Environment.getExternalStorageDirectory()

你可以在那里創建一個文件夾並保存你的文件。 如果系統允許將用戶文件保存在那里,也可以使用“/ data / local /”。 您可以參考此頁面,了解有關將文件保存到內部和外部存儲的各種方法,

對於第二個問題,我建議你使用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接口來讀取和編寫可序列化對象。 事實上,當我嘗試將數據值直接寫入文件而不是任何傳統數據庫時,我曾經使用過一次(在我的第一個大學本科,我不熟悉數據庫)。 一個很好的例子就是在這里

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())
  ;
} 

從我看到的,您正在嘗試將對象的內容轉儲到文件中,然后將其讀回。 但是你現在這樣做的方法就是將所有數據寫入文件而沒有任何結構,這是一個糟糕的主意。

我建議你嘗試實現Serializable接口 ,然后只使用writeObject()和readObject()方法。

或者,您可以將數據轉儲到XML文件或具有某種結構的文件中。

Android為每種應用程序提供了一種私有目錄結構,以實現這種數據。 您無需特殊權限即可訪問它。 唯一的警告(通常是一個很好的警告)是只有你的應用程序可以訪問它。 (此原則是安全性的一部分,可防止其他應用程序對您執行不良操作。)

如果這符合您的存儲需求,只需從任何可用的上下文(通常是您的活動)調用getFilesDir() )。 在您的情況下,您可能希望將上下文作為readData()writeData()的參數傳遞。 或者您可以調用getFilesDir()來獲取存儲目錄,然后將其作為參數傳遞給readData()writeData()

另一個警告(艱難地學習)。 雖然沒有文檔,但我發現有時Android會在這個應用程序目錄中創建文件。 我強烈建議您不要直接將文件存儲在此應用程序文件夾中,而是在getFilesDir()返回的應用程序目錄中創建自己的存儲目錄,然后將文件存儲在那里。 這樣您就不必擔心可能出現的其他文件,例如,如果您嘗試列出存儲目錄中的文件。

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

(我同意P basak, DataInputStreamDataOutputStream是讀取和寫入數據的最佳選擇。我推斷序列化,除非在一個非常狹窄的應用程序集中,可移植性是一個因素,因為它是非常低效的。在我的情況下,對象花了15使用DataInputStream在不到2秒的時間內通過Serialization加載的秒數。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM