2013-01-10 131 views
4
Bundle bundle; 
    //set data to bundle 
    //...... 


    File file = new File(context.getFilesDir().getAbsolutePath() + "/data/"); 
       FileOutputStream fos; 
       try { 
        fos = new FileOutputStream(file); 
        //fos.write 
        fos.close(); 
       } catch (FileNotFoundException exp1) { 
        exp1.printStackTrace(); 
       } catch (IOException exp2) { 
        exp2.printStackTrace(); 
       } 

我有上述代码。我想要做的就是将包保存到文件中。我发现方法写,但我不能传递一个包,但只有一个字节[]。我试图将该包转换为byte [],但我没有成功。我该怎么做才能做到这一点?什么是最有效的方法?将包保存到文件

+0

你为什么试图编写捆绑文件?相反,为什么不把数据包的数据写入文件? – Antrromet

+0

我该怎么做? –

+0

解释你为什么需要这个。 – Leonidos

回答

4

没有通用的方式来保存和从持久性存储中恢复捆绑软件。这是因为Parcel类不提供任何Android版本兼容性保证。所以我们最好不要序列化它。

但是,如果你真的想要你可以通过Parceable接口来搜索Bundle。将包转换为Parcel(writeToParcel()/ readFromParcel()),然后使用Parcel的marshall()和unmarshall()方法获取一个字节[]。保存/加载字节数组到文件。但是有一个机会,那就是有一天,如果用户将他的Android操作系统更新到更新的版本,你将无法恢复你的数据。

有一个合法的,但非常paifull和不可靠的方式来使用ObjectOutput/InputStream序列化捆绑。 (获取所有键,遍历键并将可序列化的key = value对保存到文件中,然后从文件中读取key = value对,确定值的类型,并通过合适的putXXX(key,value)方法将数据放回Bundle中)不值得)

我建议你把你的自定义的可串行化结构放在Bundle中,以存储所有需要的值,并从文件保存/加载只有这个结构。

或者找到一个更好的方式来管理你的数据而不使用Bundle。

+1

你永远不应该这样做。从'Parcel.marshall()'文档*您在这里检索的数据不得放置在任何类型的永久性存储器中(在本地磁盘上,通过网络等)。为此,您应该使用标准序列化或其他类型的通用序列化机制。 Parcel marshalled表示针对本地IPC进行了高度优化,因此不会尝试保持与在不同版本的平台上创建的数据的兼容性。 –

+1

@vmironov那么,您对序列化有什么建议? –

+0

是的,如果用户有时更新android版本,您有可能无法恢复包裹。所以不要以这种方式保存关键数据) – Leonidos

0

你可以做这样的事情

public void write(String fileName, Bundle bundle) 
    { 
     File root = Environment.getExternalStorageDirectory(); 
     File outDir = new File(root.getAbsolutePath() + File.separator + "My Bundle"); 
     if (!outDir.isDirectory()) 
     { 
      outDir.mkdir(); 
     } 
     try 
     { 
      if (!outDir.isDirectory()) 
      { 
       throw new IOException("Unable to create directory My bundle. Maybe the SD card is mounted?"); 


    } 
     File outputFile = new File(outDir, fileName); 
     writer = new BufferedWriter(new FileWriter(outputFile)); 
     String value=bundle.getString("key"); 
     writer.write(value); 
     Toast.makeText(context.getApplicationContext(), "Report successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show(); 
     writer.close(); 
    } catch (IOException e) 
    { 
     Log.w("error", e.getMessage(), e); 
     Toast.makeText(context, e.getMessage() + " Unable to write to external storage.", Toast.LENGTH_LONG).show(); 
    } 

} 

这里,想法很简单。您将Bundle传递给此方法,然后提取您拥有的任何数据(例如,在这种情况下,我们有一个字符串,其中包含键key),然后将其写入文件。

3
Bundle in=yourBundle; 
FileOutputStream fos = context.openFileOutput(localFilename, Context.MODE_PRIVATE); 
Parcel p = Parcel.obtain(); //creating empty parcel object 
in.writeToParcel(p, 0); //saving bundle as parcel 
fos.write(p.marshall()); //writing parcel to file 
fos.flush(); 
fos.close(); 
+0

在行中:in.writeToParcel(parcel,0);包裹是什么? –

+0

我很抱歉,这是我的错误,它是我们保存捆绑包的包裹对象。 –

+0

请检查我编辑的答案。 –

4

我不喜欢在我的上述评论的代码的格式,所以这是你会怎么读回了:

阅读这样的:

try { 
    FileInputStream fis = openFileInput(localFilename); 
    byte[] array = new byte[(int) fis.getChannel().size()]; 
    fis.read(array, 0, array.length); 
    fis.close(); 
    parcel.unmarshall(array, 0, array.length); 
    parcel.setDataPosition(0); 
    Bundle out = parcel.readBundle(); 
    out.putAll(out); 
} catch (FileNotFoundException fnfe) { 
} catch (IOException ioe) { 
} finally { 
    parcel.recycle(); 
} 
+1

非常感谢'setDataPosition()'提示!谁知道它必须被称为! – WindRider

+0

不要这样做。 https://developer.android.com/reference/android/os/Parcel.html表示“将任何Parcel数据放入永久存储器中并不合适” – gladed

0

这里是功能,可以帮助您将Bundle转换为JSONObject,请注意,它只会在捆绑包含int s和String s时才起作用

public static JSONObject bundleToJsonObject(Bundle bundle) { 
    try { 
     JSONObject output = new JSONObject(); 
     for(String key : bundle.keySet()){ 
      Object object = bundle.get(key); 
      if(object instanceof Integer || object instanceof String) 
        output.put(key, object); 
      else 
       throw new RuntimeException("only Integer and String can be extracted"); 
     } 
     return output; 
    } catch (JSONException e) { 
     throw new RuntimeException(e); 
    } 
} 

public static Bundle JsonObjectToBundle(JSONObject jsonObject) { 
    try { 
     Bundle bundle = new Bundle(); 
     Iterator<?> keys = jsonObject.keys(); 
     while(keys.hasNext()){ 
      String key = (String)keys.next(); 
      Object object = jsonObject.get(key); 
      if(object instanceof String) 
       bundle.putString(key, (String) object); 
      else if(object instanceof Integer) 
       bundle.putInt(key, (Integer) object); 
      else 
       throw new RuntimeException("only Integer and String can be re-extracted"); 
     } 
     return bundle; 
    } catch (JSONException e) { 
     throw new RuntimeException(e); 
    } 
} 
0

您不能将包保存到本地文件中。您将得到非序列化异常。可能有其他快捷方式存储。在阅读和构建原始对象之后并不是100%保证。

0

我最好的想法是静态可串行化或一切,因为Bundle可以从键迭代,在另一端序列化和反序列化,您可以使用json或任何其他的东西。例如,如果你会使用相同的类服务器和接收器,...

bundle-> serializable_object-> json->文件 - > serializable_object->捆绑

任何操作系统版本guaranted工作