![](/img/trans.png)
[英]Java - Files get corrupted when sent over socket, except when sent to localhost
[英]Corrupted pdf decoded and sent over Java server socket
我有一個解碼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();
任何幫助是極大的贊賞!
您使用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();
通過這些更改,代碼可為您工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.