1 回答
TA贡献1786条经验 获得超13个赞
您使用Writer和Reader类和面向文本行的方法:
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
和
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
byte[] bytes = message.getBytes();
这意味着您将数据作为文本处理。仅此一项就足以破坏二进制数据,例如 pdf 文件。
每当您将二进制数据视为文本时,都假定数据字节是根据某些字符编码(例如 Latin-1 或 UTF-8)编码的文本。但并非所有字节序列都可以正确转换为文本,有些字节序列没有文本可以编码为这些序列,特别是根据 UTF-8。这样的字节序列通常会被转换为替换字符,因此原始序列在翻译中会丢失。当字符串再次被视为字节数组时,您将获得替换字符的字符代码而不是那些序列,并且文件已损坏。
此外,您很可能会提前切断读取的数据。
BufferedReader.readLine()只读取字符直到可以解释为行分隔符的下一个字符。由于根据底层编码表示行分隔符的字节可能出现在二进制文件中的任意位置,readLine()因此很可能甚至没有读取整个(已经损坏的)PDF 文档。
根据这些提示,您更改了代码,使其不会将 PDF 视为文本:
服务器:
File f = new File("Path_to_PDF");
byte[] pdf = new byte [(int)f.length()];
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(pdf,0,pdf.length);
OutputStream os = s.getOutputStream();
os.write(pdf, 0, pdf.length);
os.flush();
客户:
int FILE_SIZE = 60000000; //just a large size
int current = 0;
byte[] pdf = new byte[FILE_SIZE];
InputStream is = s.getInputStream();
File someFile = new File(getCacheDir() + "/file.pdf");
FileOutputStream fos = new FileOutputStream(someFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = 0;
int b;
while ((b = is.read()) != -1) {
bos.write(b);
bytesRead++;
}
bos.flush();
bos.close();
fos.close();
通过这些更改,代码可以为您工作。
添加回答
举报