C#FileStream不会追加

时间:2018-01-24 15:32:36

标签: c# database filestream

我有以下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;
        }

    }

当我插入一行时,一切都很好,只要我插入另一行,它就不会显示..

这是我的选择功能

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

1 个答案:

答案 0 :(得分:0)

是的,这就是问题所在。

据我所知,序列化过程将序列化数据的长度存储在文件中。因此,如果追加数据,反序列化调用只能看到第一个序列化数据,因为它读取了要反序列化的数据的长度。

// 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...

所以你有两个选择: 按照我的第一个答案,或者,如果你想保留文件附加内容,请在formatter.Deserialize调用后获取流的位置,一次又一次地调用该函数,直到你在流的末尾。