摘要:遇到的問題在用通信傳輸一個文件以及其他的非文件的時候總是傳到服務端的文件出錯,后來發現是在用字符流和字節流在讀取各種文件上的差別所導致的讀取文件的方式字節流讀取和,其讀取的方式按字節讀取,這個常用于讀取原始數據。
遇到的問題
在用socket通信傳輸一個pdf文件以及其他的非txt文件的時候總是傳到服務端的文件出錯,后來發現是在用字符流和字節流在讀取各種文件上的差別所導致的
java讀取文件的方式字節流讀取:InputStream和OutPutStream,其讀取的方式按字節讀取,這個常用于讀取原始數據。
字符流讀取:Reader和Writer,按字節讀取數據,java里面一個字符對應兩個字節
為什么會有時候會出現亂碼在計算機中常會涉及到編碼問題,那么在字符流讀取文件的時候也會遇到一些問題,典型的就是在讀取txt文件的時候再保存遇到的亂碼,在java里面一個字符對應兩個字節,但是在UTF-8的編碼中有時候一個漢字可能對應的是三個字節,那么這個時候在讀取的時候不指定編碼的話會造成讀取文件的亂碼現象
一個txt文件假設是GBK編碼的話,在以字符流讀取的時候若依GBK讀取就會造成問題
測試(JDK1.8,IDEA,默認編碼UTF-8,txt文件編碼GBK)寫了一個代碼測試了下:
在以字節流去讀取pdf格式和其他格式的文件都沒問題,但是字節流讀取之后保存為String再寫入文件會導致pdf等文件出錯:代碼如下
此時會導致pdf文件全部是白的,音樂等文件全部錯誤,而且txt格式的文件的文字全部變成拷斤棍,至于拷斤棍百度了下是由于字符編碼問題,
File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk es.doc"); Reader reader =new InputStreamReader(new FileInputStream(file1)); int len; char[] a =new char[1024]; StringBuffer sb =new StringBuffer(); while ((len=reader.read(a))!= -1) //以字節流去讀pdf文件 { sb.append(new String(a,0,len)); } reader.close(); FileWriter fileWriter = new FileWriter(file2); // 將讀取出來的額String數據直接寫入 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close();
將讀取之后的String再次變為字節流然后再進行讀取再直接以字節流寫入:
此時如同前面一個代碼結果一樣,除了txt有編碼問題之外的文件都有問題
// File file1= new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:disk est1.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk est1.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est1.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est1.doc"); InputStream in =null; OutputStream out =null; try{ in= new FileInputStream(file1); byte[] bytes= new byte[1024]; int read =0; StringBuffer sb =new StringBuffer(); while ((read =in.read(bytes))!= -1) { sb.append(new String(bytes,0,read)); } System.out.println("a"); InputStream inputStream =new ByteArrayInputStream(sb.toString().getBytes()); byte[] re =new byte[1024]; int haveRead= 0; FileOutputStream fileOutputStream =new FileOutputStream(file2); while ((haveRead =inputStream.read(re))!= -1) { fileOutputStream.write(re,0,haveRead); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); }finally { in.close(); } }
全部以GBK格式讀取和以GBK格式寫入,除了txt文件正常以外其他的文件全部出錯
File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk est4.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est4.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est4.doc"); //拷斤棍 FileInputStream fileInputStream =new FileInputStream(file1); Reader reader =new InputStreamReader(fileInputStream,"GBK"); // txt測試GBK結果正確 DOC測試以UTF-8測試結果:拷斤棍 // char[] chars =new char[1024]; int read=0; StringBuffer sb =new StringBuffer(); while((read=reader.read(chars))!= -1) { sb.append(new String(chars,0,read)); } FileOutputStream fileOutputStream =new FileOutputStream(file2); Writer writer =new OutputStreamWriter(fileOutputStream,"GBK"); writer.write(sb.toString()); writer.flush(); writer.close();
所以在java里面對文件的讀寫最好以字節流寫入:此時無論是各種文件都沒問題,對于字符流的使用感覺是在一些需要編碼的文件,即類似于txt的文本文件。
File file1 =new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:diskcopy.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:diskcopy.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:diskcopy.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:diskcopy.doc"); InputStream in =null; OutputStream out =null; try{ in= new FileInputStream(file1); out=new FileOutputStream(file2); byte[] bytes= new byte[1024]; int read =0; StringBuffer sb =new StringBuffer(); while ((read =in.read(bytes))!= -1) { out.write(bytes,0,read); // 直接以字節流的方式輸出到文件 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { in.close(); out.close(); }
全部代碼
import java.io.*; /** * Created by szh on 2017/3/26. */ public class FileTest { /* 文件以字節流讀取 1.以這種方式讀取非文檔的 */ public static void tes() throws IOException { // File file1 =new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:disk es.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk es.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk es.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk es.doc"); Reader reader =new InputStreamReader(new FileInputStream(file1)); int len; char[] a =new char[1024]; StringBuffer sb =new StringBuffer(); while ((len=reader.read(a))!= -1) //以字節流去讀pdf文件 { sb.append(new String(a,0,len)); } reader.close(); FileWriter fileWriter = new FileWriter(file2); // 將讀取出來的額String數據直接寫入 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); } /* 以字節流來讀取文件 */ public static void test2() throws IOException { // File file1 =new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:disk est2.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk est2.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est2.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est2.doc"); byte[] sendBytes = new byte[1024]; int length = 0; StringBuffer sb =new StringBuffer(); FileInputStream fileInputStream =new FileInputStream(file1); while((length = fileInputStream.read(sendBytes, 0, sendBytes.length)) > 0){ // 將文件讀取為String sb.append(new String(sendBytes, 0, length)); } FileWriter fileWriter = new FileWriter(file2); // 這里會導致讀取出來的txt文字都是拷斤棍 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); } /* 以字節流讀取但是不讀取為String */ public static void copy() throws IOException { // File file1 =new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:diskcopy.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:diskcopy.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:diskcopy.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:diskcopy.doc"); InputStream in =null; OutputStream out =null; try{ in= new FileInputStream(file1); out=new FileOutputStream(file2); byte[] bytes= new byte[1024]; int read =0; StringBuffer sb =new StringBuffer(); while ((read =in.read(bytes))!= -1) { out.write(bytes,0,read); // 直接以字節流的方式輸出到文件 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { in.close(); out.close(); } } /* 將文件以字節流的方式讀取文件轉為String但是又重新將String轉為字節流然后寫入 */ public static void test1() throws IOException { // File file1= new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:disk est1.pdf"); // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk est1.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est1.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est1.doc"); InputStream in =null; OutputStream out =null; try{ in= new FileInputStream(file1); byte[] bytes= new byte[1024]; int read =0; StringBuffer sb =new StringBuffer(); while ((read =in.read(bytes))!= -1) { sb.append(new String(bytes,0,read)); // out.write(bytes,0,read); System.out.println(read+"-----------read的值"); } System.out.println("a"); InputStream inputStream =new ByteArrayInputStream(sb.toString().getBytes()); byte[] re =new byte[1024]; int haveRead= 0; FileOutputStream fileOutputStream =new FileOutputStream(file2); while ((haveRead =inputStream.read(re))!= -1) { fileOutputStream.write(re,0,haveRead); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); }finally { in.close(); } } /* 修改編碼 */ public static void test3() { // File file1 =new File("D:disk1Java鎖.pdf"); // File file2 =new File("D:diskcopy.pdf"); // File file1 = new File("D:disk1Java鎖.txt"); // File file2 = new File("D:disk est3.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est3.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est3.doc"); InputStream in = null; OutputStream out = null; try { in = new FileInputStream(file1); out = new FileOutputStream(file2); byte[] bytes = new byte[1024]; int read = 0; StringBuffer sb = new StringBuffer(); while ((read = in.read(bytes)) != -1) { sb.append(new String(bytes, 0, read)); } InputStream inputStream = new ByteArrayInputStream(sb.toString().getBytes()); byte[] re = new byte[1024]; int haveRead = 0; FileOutputStream fileOutputStream = new FileOutputStream(file2); StringBuffer sb2 = new StringBuffer(); while ((haveRead = inputStream.read(re)) != -1) { // fileOutputStream.write(re,0,haveRead); sb2.append(new String(re, 0, haveRead)); } OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "GBK"); // 在這里轉換的話會導致都是? outputStreamWriter.write(sb2.toString()); outputStreamWriter.close(); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } finally { } } public static void test4() throws IOException { // File file1 =new File("D:disk1Java鎖.txt"); // File file2 =new File("D:disk est4.txt"); // File file1 =new File("D:disk1Unit.wma"); // File file2 =new File("D:disk est4.wma"); File file1 =new File("D:disk1README.doc"); File file2 =new File("D:disk est4.doc"); //拷斤棍 FileInputStream fileInputStream =new FileInputStream(file1); Reader reader =new InputStreamReader(fileInputStream,"UTF-8"); // txt測試GBK結果正確 DOC測試以UTF-8測試結果:拷斤棍 // char[] chars =new char[1024]; int read=0; StringBuffer sb =new StringBuffer(); while((read=reader.read(chars))!= -1) { sb.append(new String(chars,0,read)); } FileOutputStream fileOutputStream =new FileOutputStream(file2); Writer writer =new OutputStreamWriter(fileOutputStream,"UTF-8"); writer.write(sb.toString()); writer.flush(); writer.close(); } public static void main(String args[]) throws IOException { tes(); test2(); copy(); test1(); test3(); test4(); } }
項目地址:https://github.com/Somersames...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66904.html
摘要:一面試題及剖析今日面試題今天壹哥帶各位復習一塊可能會令初學者比較頭疼的內容,起碼當時讓我很有些頭疼的內容,那就是流。在這里壹哥會從兩部分展開介紹流,即與流。除此之外盡量使用字節流。關閉此輸入流并釋放與流相關聯的任何系統資源。 一. 面試題及剖析 1. 今日面試題 今天 壹哥 帶各位復習一塊可...
摘要:是一個系統支持的所有字符的集合,包括各國家文字標點符號圖形符號數字等字符集簡體中文碼表。支持中國國內少數民族的文字,同時支持繁體漢字以及日韓漢字等字符集為表達任意語言的任意字符而設計,是業界的一種標準,也稱為統一碼標準萬國碼。 1 File1.1 File類的概述和構造方法File: 它是文件和目錄路徑名的抽象...
摘要:在包下主要包括輸入輸出兩種流,每種輸入輸出流又可分為字節流和字符流兩大類。輸入輸出是從程序運行所在的內存的角度而言的。的輸入流主要由和作為基類,而輸出流主要由和作為基類。 本章主要參考和摘自瘋狂java講義上面的(java編程思想的后面看過后有新的內容再補充進去吧)。 輸入輸出是所有程序都必需的部分————使用輸入機制允許程序讀取外部數據(包括磁盤、光盤等存儲設備上的數據和用戶輸入的...
摘要:大家好,樂字節小樂又來了。上一篇給大家帶來的是中的流之輸入流樂字節,本文將繼續講述流之輸出流。一輸出流抽象類和和也非常相似。從上述的字節數組中,讀取字符串。 大家好,樂字節小樂又來了。上一篇給大家帶來的是:Java中的IO流之輸入流|樂字節,本文將繼續講述IO流之輸出流。showImg(https://segmentfault.com/img/bVbvQx1?w=600&h=338);...
摘要:字符流字符流是什么字符流是可以直接讀寫字符的流字符流讀取字符就要先讀取到字節數據然后轉為字符如果要寫出字符需要把字符轉為字節再寫出類的方法可以按照字符大小讀取通過項目默認的碼表一次讀取一個字符賦值給將讀到的字符強轉后打印字符流類的方法可以 1_字符流FileReader 1.字符流是什么 字符流是可以直接讀寫字符的IO流 字符流讀取字符, 就要先讀取到字節數據, 然后轉為字符. ...
閱讀 2009·2021-11-24 09:39
閱讀 1878·2019-08-30 15:55
閱讀 2168·2019-08-30 15:53
閱讀 565·2019-08-29 13:16
閱讀 984·2019-08-26 12:20
閱讀 2379·2019-08-26 11:58
閱讀 3129·2019-08-26 10:19
閱讀 3296·2019-08-23 18:31