Краткое описание проблемы Формат по умолчанию, используемый сериализованным (или двоичным) кодированием, тривиально не добавляется.
Проблема (длиннее)
Вы говорите, что добавили:
S.encode (a,b)
к одному и тому же файлу "несколько раз". Итак, формат файла теперь:
[ 64 bit length field | # floats encoded | 64 length field | # floats encoded ]
Повторяется, сколько раз вы добавляли файл. То есть каждое добавление будет добавлять новые поля длины и список значений с плавающей точкой, оставляя старые значения на месте.
После этого вы вернулись, чтобы прочитать файл и декодировать некоторые поплавки, используя, морально, S.decode <$> BS.readFile path
. Это будет декодировать первые два списка с плавающей точкой, сначала читая поле длины (в первый раз, когда вы записали в файл), затем следующие значения с плавающей точкой и второе поле длины, за которым следуют связанные с ними значения с плавающей точкой. После считывания заданной длины значений float декодер остановится.
Теперь должно быть ясно, что только из-за того, что вы добавили больше данных, ваш скрипт кодирования или декодирования не будет искать никаких дополнительных данных. Формат по умолчанию, используемый сериализованным (или двоичным) кодированием, тривиально не добавляется.
* Решения 1023 *
Вы упомянули переход на Aeson, но использование JSON для кодирования вместо двоичного кода не поможет вам. Декодирование двух добавленных строк JSON, таких как { "first": [1], "second": [2]}{ "first": [3], "second": [4]}
, логически совпадает с вашей текущей проблемой. У вас есть неизвестное количество чередующихся кусков списков - просто напишите декодер, чтобы продолжить попытки:
import Data.Serialize as S
import Data.Serialize.Get as S
import Data.ByteString as BS
fromFile path = do
bstr <- BS.readFile path
let d = S.runGet getMultiChunks bstr :: Either String ([Float],[Float])
return (Right d)
getMultiChunks :: Get ([Float],[Float])
getMultiChunks = go ([], [])
where
go (l,r) = do
b <- isEmpty
if b then pure ([],[])
else do (lNext, rNext) <- S.get
go (l ++ lNext, r ++ rNext) -- inefficient
Итак, мы написали наш собственный метод получения (непроверенный), который будет проверять, останется ли байт, и если да, то декодировать другую пару списков с плавающей точкой. Каждый раз, когда он декодирует новый чанк, он добавляет старый чанк (который неэффективен, используйте что-то вроде dlist, если вы хотите, чтобы он был респектабельным).