损坏的PDF解码,并在Java服务器套接字发送

时间:2019-02-02 19:24:57

标签: java android sockets pdf networking

我有一个解码pdf并通过套接字发送它的程序。我看到很多代码堆栈溢出,但一直没能找到的东西,修复该问题。 android客户端读取文本,将其转换为字节码,然后将文件写入应该由pdfViewer加载的缓存中。在PDF阅读器作品,以及被传达给客户的信息任何测试,但是当通过套接字发送过来的文件时,PDF已损坏。该文件实际上是已创建的,如果未写入任何字节,将返回pdf为空的错误。我排除错误捕获和其他信息,因为代码的其余部分是不相关的:

服务器:

File f = new File(PATH_TO_PDF);
FileInputStream is = new FileInputStream(f);
byte[] pdf = new byte[(int)(f.length())];

int a;
int count = 0;
while ((a=is.read())!= -1){
       pdf[count] = (byte)a;
       count++;
       }

is.close();
String result = "";

for (int i = 0; i < pdf.length; i++) {
     returnMessage.append(pdf[i]);
     }

OutputStream os = s.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to the client is "+ returnMessage);
bw.flush();

//rest is closing socket stuff


客户:

 InputStream is = s.getInputStream();
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader br = new BufferedReader(isr);
 String message = br.readLine();
 s.close();

 byte[] bytes = message.getBytes();

 File someFile = new File(getCacheDir() + "/file.pdf");
 FileOutputStream fos = new FileOutputStream(someFile);
 fos.write(bytes);
 fos.flush();
 fos.close();

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您使用WriterReader类以及面向文本行的方法:

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,有些字节序列没有文本可以编码为这些序列。然后通常将此类字节序列转换为replacement character,因此原始序列在翻译中会丢失。当再次将字符串视为字节数组时,您将获得替换字符的字符代码,而不是这些序列,并且文件已损坏。

此外,您很可能会尽早切断读取的数据。

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();

通过这些更改,代码将为您服务。