Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
已通过Java服务器套接字解码并发送损坏的pdf_Java_Android_Sockets_Pdf_Networking - Fatal编程技术网

已通过Java服务器套接字解码并发送损坏的pdf

已通过Java服务器套接字解码并发送损坏的pdf,java,android,sockets,pdf,networking,Java,Android,Sockets,Pdf,Networking,我有一个程序可以解码pdf并通过套接字发送。我查看了很多关于堆栈溢出的代码,但没有找到解决问题的方法。android客户端读取文本,将其转换为字节码,并将一个文件写入缓存,该缓存应该由pdfViewer加载。在pdf查看器上进行的任何测试都是有效的,并且与客户端通信的消息也是有效的,但是当文件通过套接字发送时,pdf被破坏。文件实际上已经创建,如果没有写入字节,将返回一个错误,即pdf为空。我排除了错误捕获和其他信息,因为代码的其余部分是不相关的: 服务器: File f = new File(

我有一个程序可以解码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



非常感谢您的帮助

您使用
Writer
Reader
类和面向文本行的方法:

OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");

这意味着您可以将数据作为文本处理。仅此一项就足以损坏二进制数据,例如pdf文件

每当您将二进制数据视为文本时,数据字节都假定为根据某种字符编码(例如拉丁语-1或UTF-8)进行的文本编码。但并非所有的字节序列都能正确地转换为文本,有些字节序列没有文本可以编码为这些序列,特别是根据UTF-8。这样的字节序列通常被转换为a,因此原始序列在翻译过程中丢失。当字符串再次被视为字节数组时,您将获得替换字符的字符代码,而不是这些序列,文件将被损坏

此外,您很可能提前切断读取数据

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

通过这些更改,代码可以为您工作。

您可以使用
Writer
Reader
类。这意味着您可以将数据作为文本处理。仅此一项就足以损坏二进制数据,例如pdf文件。此外,您不显示返回消息的类型。因此,您的it操作是否合理尚不清楚。另外,当您尝试使用单个
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();