Я гуглил и читал, и я пытаюсь найти «правильный» способ сделать это, но каждый вопрос, который я читаю на SO, кажется, имеет совершенно разные ответы.
Вот суть моей проблемы. У файлов есть сигнатура типа seq тройки (a: строка, b: строка, c: Int64). Будучи новичком в f #, я до сих пор не свободно выражаю подписи типов (или, если на то пошло, понимаю их). a является именем файла, b является внутренним идентификатором, а c является значением, представляющим длину (размер) файла. baseconfig - это строка из предыдущего кода.
ignore(files
|> Seq.filter( fun(x,y,z) -> y = baseconfig) // used to filter only files we want
|> Seq.fold( fun f n ->
if( (fun (_,_,z) -> z) n > 50L*1024L*1024L) then
zipfilex.Add((fun (z:string, _, _) -> z) n)
printfn("Adding 50mb to zip")
zipfilex.CommitUpdate()
zipfilex.BeginUpdate()
("","",0L)
else
zipfilex.Add((fun (z, _, _) -> z) n)
("", "", (fun (_, _, z:Int64) -> z) n + (fun (_, _, z:Int64) -> z) f)
) ("","",0L)
)
То, что должен делать этот кусок кода, это перебирать каждый файл в files
, добавлять его в zip-архив (но на самом деле, он просто попадает в список для последующей фиксации), и когда файлы превышать 50 МБ, зафиксируйте ожидающие файлы в zip-архиве. Добавление файла - это дешево, фиксация - это дорого, поэтому я стараюсь снизить стоимость, группируя его.
Пока что код вроде работает ... За исключением исключения ObjectDisposedException, которое я получил, когда оно приблизилось к 150 МБ зафиксированных файлов. Но я не уверен, что это правильный способ сделать такую операцию. Такое чувство, что я использую Seq.fold
нетрадиционным способом, но пока я не знаю лучшего способа сделать это.
Бонусный вопрос: есть ли лучший способ вырезать значения из кортежей? fst и snd работают только для двухзначных кортежей, и я понимаю, что вы можете определять свои собственные функции вместо встроенных, как я, но, похоже, должен быть лучший способ.
Обновление: мои предыдущие попытки сбрасывать, я не мог понять, почему я не мог просто использовать Int64 в качестве аккумулятора. Оказывается, я пропустил некоторые критические скобки. Немного более простая версия ниже. Также устраняет все сумасшедшие извлечения кортежей.
ignore(foundoldfiles
|> Seq.filter( fun (x,y,z) -> y = baseconfig)
|> Seq.fold( fun (a) (f,g,j) ->
zipfilex.Add( f)
if( a > 50L*1024L*1024L) then
printfn("Adding 50mb to zip")
zipfilex.CommitUpdate()
zipfilex.BeginUpdate()
0L
else
a + j
) 0L
)
Обновление 2 : мне нужно будет обратиться к императивному решению, F # каким-то образом повторно вводит этот блок кода после того, как zip-файл закрыт в инструкции, которая следует Это. Что объясняет исключение ObjectDisposedException. Не знаю, как это работает или почему.