REST:上传大文件

时间:2014-01-03 11:34:35

标签: rest asyncfileupload

我想知道使用REST上传大文件的推荐方法是什么。

假设服务器在磁盘上写入文件的时间可能很长,我应该等待写入操作结束,然后再将201回复发送给客户端吗?

是否可以更快地回复用户并稍后处理写入操作?在第二种情况下,我应该返回什么http状态?事实上,即使我返回201,也没有人可以确保写作操作成功。

1 个答案:

答案 0 :(得分:4)

在您从HTTP读取最后一个字节之前,听起来似乎没有开始写入磁盘。这有两个不良影响:

  1. 您将大量数据放入服务器的内存中
  2. 您将所有磁盘IO推送到请求处理的末尾,导致从客户端角度看起来不好的暂停。在极端情况下,客户可能会超时。
  3. 相反,您需要流式传输。只要您从客户端获得某些数据,就开始写入磁盘。当客户端发送其最终块时,您只需要在发送201响应之前处理该小块。

    如果您使用的API不允许您以流方式使用HTTP实体,我担心您需要寻找其他API。

    例如,在Java Servlet API中,您可以获取请求内容的InputStream:

    InputStream content = request.getInputStream();
    
    // do something better than this
    OutputStream out = new FileOutputStream("content.txt");
    byte[] buffer = new byte[1024];
    int len;
    while ((len = in.read(buffer)) != -1) {
        // whatever processing you want here
        out.write(buffer, 0, len);
    }
    
    // now you can send the 201
    

    了解当您在此示例中获得InputStream时,您的服务器尚未开始从TCP堆栈中读取内容(*),这一点非常重要。只读过标题。如果它是一个大文件,那么客户端很可能此时仍在发送。你在一个循环中读取一个块,写一个块。


    (*)这是一个简化。它可能在缓冲区中。但从概念上讲,你可以忽略