[英]C# FileStream doesn't append
I have the following C# script: 我有以下C#脚本:
public bool Insert(QueryBuilder builder) {
try {
using (FileStream fs = new FileStream(GetFinalPath(builder.GetFileName()), FileMode.Append, FileAccess.Write)) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, builder.GetModels());
}
return true;
} catch (IOException e) {
return false;
}
}
When I insert one row everything is fine, as soon as I insert another row, it doesn't show up.. 当我插入一行时,一切都很好,只要插入另一行,它就不会显示。
Here is my Select Function 这是我的选择功能
public Collection Select(QueryBuilder builder) {
List<Model> result = new List<Model>();
List<Model> resultHistory = new List<Model>();
Collection collection = new Collection();
try {
using (FileStream fs = new FileStream(GetFinalPath(builder.GetFileName()), FileMode.Open, FileAccess.Read)) {
// check if file isn't empty
if (fs.Length > 0) {
BinaryFormatter formatter = new BinaryFormatter();
result = (List<Model>) formatter.Deserialize(fs);
}
}
// TODO: check this select
if (builder.IsWithHistory()) {
using (FileStream fs = new FileStream(GetFinalPath(builder.GetBackupFileName()), FileMode.Open, FileAccess.Read)) {
// check if file isn't empty
if (fs.Length > 0) {
BinaryFormatter formatter = new BinaryFormatter();
resultHistory = (List<Model>) formatter.Deserialize(fs);
}
}
}
} catch (IOException e) {
}
// check if there are criterias
if (builder.IsSelectAll()) {
collection = new Collection(result, resultHistory);
} else {
var resultList = new List<Model>();
var historyList = new List<Model>();
// loop through initial result
for (int i = 0; i < result.Count; i++) {
var model = result[i];
var properties = model.GetType().GetProperties();
// go through each property of the model
foreach (var property in properties) {
// go through each criteria of the builder map
foreach (var fieldItem in builder.GetMap()) {
// check if criteria is available in the properties
if (property.Name == fieldItem.Key) {
// check if value is equal
// TODO: add string operation support
if (property.GetValue(model).Equals(fieldItem.Value)) {
resultList.Add(model);
}
}
}
}
}
// loop through history result
for (int i = 0; i < resultHistory.Count; i++) {
var model = result[i];
var properties = model.GetType().GetProperties();
// go through each property of the model
foreach (var property in properties) {
// go through each criteria of the builder map
foreach (var fieldItem in builder.GetMap()) {
// check if criteria is available in the properties
if (property.Name == fieldItem.Key) {
// check if value is equal
// TODO: add string operation support
if (property.GetValue(model).Equals(fieldItem.Value)) {
historyList.Add(model);
}
}
}
}
}
collection = new Collection(resultList, historyList);
}
return collection;
}
Yes, and that's the problem. 是的,这就是问题所在。
As far as I know the serialization process stores the length of the serialized data in the file. 据我所知,序列化过程将序列化数据的长度存储在文件中。 So if you append the data, the deserialization call can only see the first serialized data, since it reads the length of the data to be deserialized.
因此,如果附加数据,则反序列化调用只能看到第一个序列化的数据,因为它读取了要反序列化的数据的长度。
// Our data to be serialized
str1 = "ThisIsATest"; // length=11
str2 = "Trash"; // length=5
// Thats what the serializer does: Write the length of the data, write the acutal data. The pipe is not written, just for better readability
// Initial file write...
11|ThisIsATest
// Appending the second string
11|ThisIsATest|5|Trash
// The raw file content
11ThisIsATest5Trash
// The deserializer reads the length field and then the number of
// bytes as data and ends there. It does not know that there is other
// data following, since you used to separate serialization calls...
So you have two options: Follow my first answer, or, if you want to keep the file appending stuff, get the position of the stream after your formatter.Deserialize
call, call the function again and again until you are at the end of the stream. 因此,您有两个选择:遵循我的第一个答案,或者,如果要保持文件追加内容,请在
formatter.Deserialize
之后获取流的位置。反formatter.Deserialize
调用,一次又一次调用该函数,直到到达末尾为止。流。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.