问题
I would like to store a string[][]-array in a database as datatype "blob". I just found out that I have to convert it, otherwise the data would be practically lost. What would be the best way to do that?
I suppose I should serialize and de-serialize the array, unfortunately I am not quite experienced in that area. So any help would be appreciated.
PS: I guess I should have said that I need to do that on Android, thus using SQLite. The string[][] has no fixed number of rows or columns.
回答1:
Why a blob? Why not a clob? Or better yet, why not a varchar? Depending on what you're going to do with the data, you should store the data as xml or json in a varchar column. It would be searchable too, if necessary.
You didn't say what's in your array but possibly another table would fit the bill, though determining that is far outside the scope of this question (it would make a good new question though).
No, far better to serialize your array as text and store it as such.
Edit... A library like JSON-lib supports bi-directional serialization on multidimensional arrays. Just run your array through JSON-lib to get a JSON string, store that string, then when you want your array back run the string through JSON-lib.
I prefer my text to be in the database as text so I can search for it and view it with one of the many database tools available. I don't want to run code to see what's in a column, and if I need to tweak a value by hand during development I want to be able to update the value, not run a program to do it for me.
回答2:
Okay, assuming there won't be nulls. Write out:
- The number of "rows" as a fixed 4-byte value
- For each "row":
- The number of "columns" as a fixed 4-byte value
- For each string:
- Convert the string in bytes, e.g. in UTF-8 (
text.getBytes("UTF-8")
) - Write out the number of bytes as a fixed 4-byte value
- Write out the data for the string
- Convert the string in bytes, e.g. in UTF-8 (
You could just use DataOutputStream
's writeUTF
method for the last part, but that would make it slightly harder to read from non-Java platforms. It depends on your requirements. Using DataOutputStream
would make it easier to handle in general though. For example:
private static final Charset UTF8 = Charset.forName("UTF-8");
private static byte[] SerializeText(String[][] array)
{
int rows = array.length;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(rows);
for (int i = 0; i < rows; i++)
{
int columns = array[i].length;
dos.writeInt(columns);
for (int j = 0; j < columns; j++)
{
byte[] utf8 = array[i][j].getBytes(UTF8);
dos.writeInt(utf8.length);
dos.write(utf8, 0, utf8.length);
}
}
dos.flush(); // May not be necessary
return baos.toByteArray();
}
回答3:
Instead of XML, I just discovered a JSON library (thanks to this question), named google gson.
You just have to add the .jar to your classpath, and I give you the code for serialization and deserialization:
import com.google.gson.Gson;
public class JsonTest {
public static void main(String[] args) {
String[][] fruits = { { "Banana", "Apple", "Blueberry" }, { "Cherry" }, { "Lemon", "Mango" } };
Gson gson = new Gson();
// Serialization
String json = gson.toJson(fruits);
// Print: [["Banana","Apple","Blueberry"],["Cherry"],["Lemon","Mango"]]
System.out.println(json);
// Deserialization
String[][] result = gson.fromJson(json, String[][].class);
}
}
I am really happy that I found this library, XML was too much verbose.
(Sorry for spelling mistakes, I am French.)
回答4:
You can store it as xml with the xstream library.
It is not very effective due to xml tags, but it works well and it is easy to use:
String[][] strs = {
{ "row1_col1", "row1_col2", "row1_col3" },
{ "row2_col1" },
{ "row3_col1", "row3_col2" }
};
XStream xstream = new XStream();
xstream.alias("saa", String[][].class);
xstream.alias("sa", String[].class);
xstream.alias("s", String.class);
String xml = xstream.toXML(str);
System.out.println(xml);
The result:
<saa>
<sa>
<s>row1_col1</s>
<s>row1_col2</s>
<s>row1_col3</s>
</sa>
<sa>
<s>row2_col1</s>
</sa>
<sa>
<s>row3_col1</s>
<s>row3_col2</s>
</sa>
</saa>
Deserialize:
String[][] strs = (String[][])xstream.fromXML(xml);
回答5:
I found a solution that works for me.
The main problem was that apparently the BLOB has not been saved properly in the database. I used the Android convenience methods to update the database, and now it works even better than I first anticipated.
来源:https://stackoverflow.com/questions/6809179/storing-a-string-array-in-a-database