diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+## 1.2.2
+
+* `sinkHandleBuilder`, `sinkHandleFlush`, `BuilderInput`, and `FlushInput`
+  [#336](https://github.com/snoyberg/conduit/pull/336)
+* `withSinkFileCautious`
+
 ## 1.2.1
 
 * `Data.Conduit.Process.Typed`
diff --git a/Data/Conduit/Binary.hs b/Data/Conduit/Binary.hs
--- a/Data/Conduit/Binary.hs
+++ b/Data/Conduit/Binary.hs
@@ -28,8 +28,11 @@
     , sinkSystemTempFile
     , sinkHandle
     , sinkIOHandle
+    , sinkHandleBuilder
+    , sinkHandleFlush
     , withSinkFile
     , withSinkFileBuilder
+    , withSinkFileCautious
       -- ** Conduits
     , conduitFile
     , conduitHandle
@@ -53,6 +56,7 @@
     , Data.Conduit.Binary.lines
     ) where
 
+import qualified Data.ByteString.Builder as BB
 import qualified Data.Streaming.FileRead as FR
 import Prelude hiding (head, take, drop, takeWhile, dropWhile, mapM_)
 import qualified Data.ByteString as S
@@ -61,7 +65,7 @@
 import Data.Conduit
 import Data.Conduit.List (sourceList, consume)
 import qualified Data.Conduit.List as CL
-import Control.Exception (assert, finally)
+import Control.Exception (assert, finally, bracket)
 import Control.Monad (unless, when)
 import Control.Monad.IO.Class (liftIO, MonadIO)
 import Control.Monad.IO.Unlift
@@ -167,7 +171,7 @@
 sourceIOHandle alloc = bracketP alloc IO.hClose sourceHandle
 
 -- | Stream all incoming data to the given 'IO.Handle'. Note that this function
--- will /not/ automatically close the @Handle@ when processing completes.
+-- does /not/ flush and will /not/ close the @Handle@ when processing completes.
 --
 -- Since 0.3.0
 sinkHandle :: MonadIO m
@@ -175,6 +179,29 @@
            -> Consumer S.ByteString m ()
 sinkHandle h = awaitForever (liftIO . S.hPut h)
 
+-- | Stream incoming builders, executing them directly on the buffer of the
+-- given 'IO.Handle'. Note that this function does /not/ automatically close the
+-- @Handle@ when processing completes.
+-- Pass 'Data.ByteString.Builder.Extra.flush' to flush the buffer.
+--
+-- @since 1.2.2
+sinkHandleBuilder :: MonadIO m => IO.Handle -> ConduitM BB.Builder o m ()
+sinkHandleBuilder h = awaitForever (liftIO . BB.hPutBuilder h)
+
+-- | Stream incoming @Flush@es, executing them on @IO.Handle@
+-- Note that this function does /not/ automatically close the @Handle@ when
+-- processing completes
+--
+-- @since 1.2.2
+sinkHandleFlush :: MonadIO m
+                => IO.Handle
+                -> ConduitM (Flush S.ByteString) o m ()
+sinkHandleFlush h =
+  awaitForever $ \mbs -> liftIO $
+  case mbs of
+    Chunk bs -> S.hPut h bs
+    Flush -> IO.hFlush h
+
 -- | An alternative to 'sinkHandle'.
 -- Instead of taking a pre-opened 'IO.Handle', it takes an action that opens
 -- a 'IO.Handle' (in write mode), so that it can open it only when needed
@@ -274,15 +301,8 @@
   => FilePath
   -> ConduitM S.ByteString o m ()
 sinkFileCautious fp =
-    bracketP acquire cleanup inner
+    bracketP (cautiousAcquire fp) cautiousCleanup inner
   where
-    acquire = openBinaryTempFile (takeDirectory fp) (takeFileName fp <.> "tmp")
-    cleanup (tmpFP, h) = do
-        hClose h
-        removeFile tmpFP `Control.Exception.catch` \e ->
-            if isDoesNotExistError e
-                then return ()
-                else throwIO e
     inner (tmpFP, h) = do
         sinkHandle h
         liftIO $ do
@@ -634,3 +654,34 @@
   withRunInIO $ \run ->
   IO.withBinaryFile fp IO.ReadMode $ \h ->
   run $ inner $ CL.mapM_ (liftIO . BB.hPutBuilder h)
+
+-- | Like 'sinkFileCautious', but uses the @with@ pattern instead of
+-- @MonadResource@.
+--
+-- @since 1.2.2
+withSinkFileCautious
+  :: (MonadUnliftIO m, MonadIO n)
+  => FilePath
+  -> (ConduitM S.ByteString o n () -> m a)
+  -> m a
+withSinkFileCautious fp inner =
+  withRunInIO $ \run -> bracket
+    (cautiousAcquire fp)
+    cautiousCleanup
+    (\(tmpFP, h) -> do
+        a <- run $ inner $ sinkHandle h
+        renameFile tmpFP fp
+        return a)
+
+-- | Helper function for Cautious functions above, do not export!
+cautiousAcquire :: FilePath -> IO (FilePath, IO.Handle)
+cautiousAcquire fp = openBinaryTempFile (takeDirectory fp) (takeFileName fp <.> "tmp")
+
+-- | Helper function for Cautious functions above, do not export!
+cautiousCleanup :: (FilePath, IO.Handle) -> IO ()
+cautiousCleanup (tmpFP, h) = do
+  hClose h
+  removeFile tmpFP `Control.Exception.catch` \e ->
+    if isDoesNotExistError e
+      then return ()
+      else throwIO e
diff --git a/Data/Conduit/Process.hs b/Data/Conduit/Process.hs
--- a/Data/Conduit/Process.hs
+++ b/Data/Conduit/Process.hs
@@ -28,8 +28,9 @@
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import System.IO (hClose)
 import Data.Conduit
-import Data.Conduit.Binary (sourceHandle, sinkHandle)
+import Data.Conduit.Binary (sourceHandle, sinkHandle, sinkHandleBuilder, sinkHandleFlush)
 import Data.ByteString (ByteString)
+import Data.ByteString.Builder (Builder)
 import Control.Concurrent.Async (runConcurrently, Concurrently(..))
 import Control.Monad.Catch (MonadMask, onException, throwM, finally, bracket)
 #if (__GLASGOW_HASKELL__ < 710)
@@ -40,6 +41,28 @@
     isStdStream = (\(Just h) -> return $ sinkHandle h, Just CreatePipe)
 instance (r ~ (), r' ~ (), MonadIO m, MonadIO n, i ~ ByteString) => InputSource (ConduitM i o m r, n r') where
     isStdStream = (\(Just h) -> return (sinkHandle h, liftIO $ hClose h), Just CreatePipe)
+
+-- | Wrapper for input source which accepts 'Data.ByteString.Builder.Builder's.
+-- You can pass 'Data.ByteString.Builder.Extra.flush' to flush the input. Note
+-- that the pipe will /not/ automatically close when the processing completes.
+--
+-- @since 1.2.2
+newtype BuilderInput o m r = BuilderInput (ConduitM Builder o m r)
+
+-- | Wrapper for input source  which accepts @Flush@es. Note that the pipe
+-- will /not/ automatically close then processing completes.
+--
+-- @since 1.2.2
+newtype FlushInput o m r = FlushInput (ConduitM (Flush ByteString) o m r)
+
+instance (MonadIO m, r ~ ()) => InputSource (BuilderInput o m r) where
+  isStdStream = (\(Just h) -> return $ BuilderInput $ sinkHandleBuilder h, Just CreatePipe)
+instance (MonadIO m, MonadIO n, r ~ (), r' ~ ()) => InputSource (BuilderInput o m r, n r') where
+  isStdStream = (\(Just h) -> return (BuilderInput $ sinkHandleBuilder h, liftIO $ hClose h), Just CreatePipe)
+instance (MonadIO m, r ~ ()) => InputSource (FlushInput o m r) where
+  isStdStream = (\(Just h) -> return $ FlushInput $ sinkHandleFlush h, Just CreatePipe)
+instance (MonadIO m, MonadIO n, r ~ (), r' ~ ()) => InputSource (FlushInput o m r, n r') where
+  isStdStream = (\(Just h) -> return (FlushInput $ sinkHandleFlush h, liftIO $ hClose h), Just CreatePipe)
 
 instance (r ~ (), MonadIO m, o ~ ByteString) => OutputSink (ConduitM i o m r) where
     osStdStream = (\(Just h) -> return $ sourceHandle h, Just CreatePipe)
diff --git a/conduit-extra.cabal b/conduit-extra.cabal
--- a/conduit-extra.cabal
+++ b/conduit-extra.cabal
@@ -1,5 +1,5 @@
 Name:                conduit-extra
-Version:             1.2.1
+Version:             1.2.2
 Synopsis:            Batteries included conduit: adapters for common libraries.
 Description:
     The conduit package itself maintains relative small dependencies. The purpose of this package is to collect commonly used utility functions wrapping other library dependencies, without depending on heavier-weight dependencies. The basic idea is that this package should only depend on haskell-platform packages and conduit.
