我遇到一种情况,我需要以这种格式从后端向前端传输对象:
{
filename: "filename",
type: "type",
src: "src",
bytes: "base64Representation"
}
对象的bytes属性包含存储在远程服务器的存储库中的文件的base64表示形式。到目前为止,我已经处理了1-2MB的小文件,并且将文件转换为相应的base64表示形式的代码已经正常工作。但是现在我遇到了大于100MB的大文件的一些问题。我已经检查了尝试逐块转换文件块的解决方案,但仍然在过程结束时,我需要将所有块串联在一个字符串中,并且在此步骤中,我遇到 OutOfMemory 异常。我还看到了一些使用 OutputStreams 的建议,但由于我需要上述格式的数据,因此无法应用它们。请问有人对我如何绕过这种情况有任何建议吗?
答案 0 :(得分:1)
您可以使用OutputStream并通过包装response.getOutputStream()
在servlet中进行动态处理。我将用Spring Boot给出一个工作示例。我已经测试过并且可以正常工作。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;
@RestController
public class Base64Controller {
@RequestMapping(value = "/base64", method = RequestMethod.GET)
public void getBase64File(HttpServletResponse response) throws IOException {
response.setContentType("text/plain");
OutputStream wrap = Base64.getEncoder().wrap(response.getOutputStream());
FileInputStream fis = new FileInputStream("./temp.txt");
int bytes;
byte[] buffer = new byte[2048];
while ((bytes=fis.read(buffer)) != -1) {
wrap.write(buffer, 0, bytes);
}
fis.close();
wrap.close();
}
}
答案 1 :(得分:1)
这里的JSON响应非常麻烦,因为Base64的有效负载为每字节6/8,因此您可以根据需要增加33%的数据传输。确实,JSON DOM对象使服务器和客户端都过度拉伸。
因此将其转换为简单的二进制下载文件,并将其流式传输出去;可能因大数据而受到限制。
这意味着API发生了变化。
答案 2 :(得分:0)
我从来没有使用struts,所以我不确定是否可以使用它,但是应该是这样的
public class DownloadB64Action extends Action{
private final static BUFFER_SIZE = 1024;
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setContentType("text/plain");
try
{
FileInputStream in =
new FileInputStream(new File("myfile.b64"));
ServletOutputStream out = Base64.getEncoder().wrap(response.getOutputStream());
byte[] buffer = new byte[BUFFER_SIZE];
while(in.read(buffer, 0, BUFFER_SIZE) != -1){
out.write(buffer, 0, BUFFER_SIZE);
}
in.close();
out.flush();
out.close();
}catch(Exception e){
//TODO handle exception
}
return null;
}
}
要使其成为所需的JSON结构,您可以尝试在b64有效负载之前直接写入response.getOutputStream()
"{\"filename\":\"filename\",\"type\":\"type\",\"src\":\"src\",\"bytes\": \"".getBytes()
,在b64有效负载之后直接写入"\"}".getBytes()
}