高效的大文件的上传与耶索德(Efficient large file upload with Yes

2019-07-29 17:25发布

我想实现我的耶索德应用大文件的上传。 现在,我有:

module Handler.File where

import Import

import System.Random
import System.FilePath
import Control.Monad
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text.Encoding

-- upload

uploadDirectory :: FilePath -- FIXME: make this configurable
uploadDirectory = "incoming"

randomFileName :: IO FilePath
randomFileName = do
  fname'base <- replicateM 20 (randomRIO ('a','z'))
  let fname = uploadDirectory </> fname'base <.> "bin"
  return fname

fileUploadForm :: Form (FileInfo, Textarea)
fileUploadForm = renderDivs $ (,)
    <$> fileAFormReq "Choose a file"
    <*> areq textareaField "What's on the file?" Nothing

getFileNewR :: Handler RepHtml
getFileNewR = do
  (formWidget, formEnctype) <- generateFormPost fileUploadForm
  defaultLayout $ do
       setTitle "Upload new file."
       $(widgetFile "file-new")

postFileNewR :: Handler RepHtml
postFileNewR = do
  user <- requireAuth
  ((result, formWidget), formEnctype) <- runFormPost fileUploadForm
  case result of
    FormSuccess (fi,info) -> do
                 fn <- liftIO randomFileName
                 liftIO (LBS.writeFile fn (fileContent fi))
                 let newFile = File (entityKey user) fn info (fileName fi) (fileContentType fi)
                 fid <- runDB $ insert newFile
                 redirect (FileViewR fid)
    _ -> return ()

  defaultLayout $ do
       setTitle "Upload new file."
       $(widgetFile "file-new")

这主要是很好,除了几个问题:

  1. 文件的最大尺寸约为2兆字节。 我有一个解决方法,但它这样做正确的方式? 我的修复是压倒maximumContentLength方法的默认实现耶索德情况下我的应用程序,就像这样:

    maximumContentLength _(只是(FileNewR _))= 2 * 1024 * 1024 * 1024 - 2千兆字节maximumContentLength _ _ = 2 * 1024 * 1024 - 2兆字节

  2. 的存储器中所用的量等于一个文件的大小。 这实在是不理想的。 我想用tempFileBackEnd从http://hackage.haskell.org/packages/archive/wai-extra/1.2.0.4/doc/html/Network-Wai-Parse.html ,但我不知道如何实际连线,在我的请求,并使其与形式逻辑(隐藏_token场等)工作。

  3. 上传是“单发”:如何使其与基于Flash / HTML5上传,显示用户的工作正在进行中任何的例子吗?

Answer 1:

  1. 您的解决方案是正确的。 该maximumContentLength设置的目的是让你来覆盖需要更大上传特定路线此值。

  2. 这是文件处理的耶索德核心的当前设置的一个缺点。 它是目前硬编码为使用内存文件上传。 我们已经在过去,这是最理想的邮件列表上讨论。 我刚刚创建了Github的问题,这一点,和修补程序将包含在耶索德1.1(上发布尚无时间表虽然)。

  3. 我没有这样的一个例子,对不起。



文章来源: Efficient large file upload with Yesod
标签: haskell yesod