简体   繁体   English

C#FileStream不追加

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM