将字节数组写入文件出现损坏文件问题

3

我在servlet的请求参数中获取了byte [],然后将其转换为字符串,再将其转换回byte []:

String encodingScheme = "UTF-8";
request.setCharacterEncoding(encodingScheme);
String requestStr = request.getParameter("inputstream");
byte[] rawRequestMsg = requestStr.getBytes(encodingScheme);

现在我正在尝试将这个byte[]写入一个.docx文件,因为我使用的byte[]是docx文件的byte[]表示。用于将其写入文件的代码如下:

String uploadedFileLocation = fileLocation;
FileOutputStream fileOuputStream = new FileOutputStream("path till .docx file");
fileOuputStream.write(byteArray);
fileOuputStream.close();

问题在于生成的.docx文件已经损坏并且无法打开,但是当我将其更改为.doc时,我可以打开它,但是我只能看到类似下面的byte[]序列,而不是文本内容:

80, 75, 3, 4, 20, 0, 6, 0, 8, 0, 0, 0, 33, 0, -84, -122, 80, 87, -114, 1, 0, 0, -64, 5, 0, 0, 19, 0, 8, 2, 91, 67, 111, 110, 116, 101, 110, 116, 95, 84, 121, 112, 101, 115, 93, 46, 120, 109, 108, 32, -94, 4, 2, 40, -96, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 

不知道如何正确地编写它。 需要帮助。 谢谢, Samir

实际上下面的代码曾经可以工作,它是一个REST webservice。

@
POST@ Path("/binaryfileupload/{filename}")@ Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response upload(byte[] input, @PathParam("filename") String filename) {
  FileOutputStream fileOuputStream = new FileOutputStream(uploadedFileLocation);
  fileOuputStream.write(input);
  fileOuputStream.close();
}

我做出的唯一更改是将byte[]输入发送到servlet,并在servlet中写入文件,而不是在我的webservice中编写(这在以前是正常工作的)。


请查看此链接:http://stackoverflow.com/questions/25890776/java-bytearray-to-docx。也许那里的解决方案可以将带有byte[]的DOC转换为正确的DOCX格式。 - Milind Gokhale
看起来你正在将输入流解释为UTF-8……但这确实是你的输入编码格式吗?例如,你是否可能收到了一个GZIP编码的字节流作为真正的输入? - Michael Aaron Safyan
我已经编辑了帖子,并添加了更多信息,排除了不正确的文档格式UTF-8 GZIP编码等可能性。 - samir
请求已经具有正确的字符编码。我很想看看客户端如何发布此“inputstream”参数。 - user207421
@EJP 我正在使用以下代码:OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); writer.write("inputstream="+Arrays.toString(input)); writer.close();这里的input是byte[]。 - samir
显示剩余5条评论
2个回答

0

我认为问题在于编码格式。我认为对于 .doc 和 .docx 文件,UTF-8 不是正确的编码格式。请参阅此线程以获取更多详细信息:https://dev59.com/El4c5IYBdhLWcg3wOoEH - Sachin Gupta
但是在Web服务方法中,您没有设置任何字符编码。但是在Servlet中,您明确设置编码为UTF-8。编码在字符串转字节的转换中扮演的主要区别。 - Sachin Gupta
这里没有任何证据说明输入是什么。 - user207421
@EJP 这里的输入是一个简单的docx文件,我将其作为二进制形式的POSTMaster工具发布到我的webservice,并在我的webservice的byte[]参数中获取它,现在如果我在那里将该byte[]写入文件,它可以正常工作。但是,我想使用POST请求将该byte[]发送到我的servlet,并在我的servlet中进行编写操作。在servlet中将byte[]写入文件的代码与我在webservice中使用的代码完全相同。此外,byte[]数据也是相同的。如果需要更多信息,请告诉我。 - samir
我认为你可以在servlet中使用request.getInputStream();来获取byte[]数据。不需要进行所有的字符串处理。 - Sachin Gupta
显示剩余2条评论

0

我终于解决了。我犯了一个小错误。在代码中。

String requestStr = request.getParameter("inputstream");
byte[] rawRequestMsg = requestStr.getBytes(encodingScheme);

我实际上将字符串转换为字节,即使它已经是字节。这就是为什么requestStr的值与rawRequestMsg不同的原因。最后,我使用了下面的代码,它将字符串简单地转换为数组,并通过逐个分离每个数字来创建byte[]:

String requestStr = request.getParameter("inputstream");
requestStr = requestStr.substring(1, requestStr.length() - 1);
String dataArray[] = requestStr.split(",");
byte[] rawRequestMsg = new byte[dataArray.length];
int count = 0;
for (String str: dataArray) {
  str = str.trim();
  rawRequestMsg[count++] = Byte.parseByte(str);
}

trim函数用于删除空格,因为它们以75、-84、3等形式出现。而substring函数则用于删除开头的 [ 和结尾的 ]。 感谢大家的帮助。 希望这能帮到其他人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接