摘要:遇到的問(wèn)題在用通信傳輸一個(gè)文件以及其他的非文件的時(shí)候總是傳到服務(wù)端的文件出錯(cuò),后來(lái)發(fā)現(xiàn)是在用字符流和字節(jié)流在讀取各種文件上的差別所導(dǎo)致的讀取文件的方式字節(jié)流讀取和,其讀取的方式按字節(jié)讀取,這個(gè)常用于讀取原始數(shù)據(jù)。
遇到的問(wèn)題
在用socket通信傳輸一個(gè)pdf文件以及其他的非txt文件的時(shí)候總是傳到服務(wù)端的文件出錯(cuò),后來(lái)發(fā)現(xiàn)是在用字符流和字節(jié)流在讀取各種文件上的差別所導(dǎo)致的
java讀取文件的方式字節(jié)流讀取:InputStream和OutPutStream,其讀取的方式按字節(jié)讀取,這個(gè)常用于讀取原始數(shù)據(jù)。
字符流讀取:Reader和Writer,按字節(jié)讀取數(shù)據(jù),java里面一個(gè)字符對(duì)應(yīng)兩個(gè)字節(jié)
為什么會(huì)有時(shí)候會(huì)出現(xiàn)亂碼在計(jì)算機(jī)中常會(huì)涉及到編碼問(wèn)題,那么在字符流讀取文件的時(shí)候也會(huì)遇到一些問(wèn)題,典型的就是在讀取txt文件的時(shí)候再保存遇到的亂碼,在java里面一個(gè)字符對(duì)應(yīng)兩個(gè)字節(jié),但是在UTF-8的編碼中有時(shí)候一個(gè)漢字可能對(duì)應(yīng)的是三個(gè)字節(jié),那么這個(gè)時(shí)候在讀取的時(shí)候不指定編碼的話會(huì)造成讀取文件的亂碼現(xiàn)象
一個(gè)txt文件假設(shè)是GBK編碼的話,在以字符流讀取的時(shí)候若依GBK讀取就會(huì)造成問(wèn)題
測(cè)試(JDK1.8,IDEA,默認(rèn)編碼UTF-8,txt文件編碼GBK)寫了一個(gè)代碼測(cè)試了下:
在以字節(jié)流去讀取pdf格式和其他格式的文件都沒(méi)問(wèn)題,但是字節(jié)流讀取之后保存為String再寫入文件會(huì)導(dǎo)致pdf等文件出錯(cuò):代碼如下
此時(shí)會(huì)導(dǎo)致pdf文件全部是白的,音樂(lè)等文件全部錯(cuò)誤,而且txt格式的文件的文字全部變成拷斤棍,至于拷斤棍百度了下是由于字符編碼問(wèn)題,
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) //以字節(jié)流去讀pdf文件 { sb.append(new String(a,0,len)); } reader.close(); FileWriter fileWriter = new FileWriter(file2); // 將讀取出來(lái)的額String數(shù)據(jù)直接寫入 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close();
將讀取之后的String再次變?yōu)樽止?jié)流然后再進(jìn)行讀取再直接以字節(jié)流寫入:
此時(shí)如同前面一個(gè)代碼結(jié)果一樣,除了txt有編碼問(wèn)題之外的文件都有問(wèn)題
// 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文件正常以外其他的文件全部出錯(cuò)
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測(cè)試GBK結(jié)果正確 DOC測(cè)試以UTF-8測(cè)試結(jié)果:拷斤棍 // 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里面對(duì)文件的讀寫最好以字節(jié)流寫入:此時(shí)無(wú)論是各種文件都沒(méi)問(wèn)題,對(duì)于字符流的使用感覺(jué)是在一些需要編碼的文件,即類似于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); // 直接以字節(jié)流的方式輸出到文件 } } 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 { /* 文件以字節(jié)流讀取 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) //以字節(jié)流去讀pdf文件 { sb.append(new String(a,0,len)); } reader.close(); FileWriter fileWriter = new FileWriter(file2); // 將讀取出來(lái)的額String數(shù)據(jù)直接寫入 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); } /* 以字節(jié)流來(lái)讀取文件 */ 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); // 這里會(huì)導(dǎo)致讀取出來(lái)的txt文字都是拷斤棍 fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); } /* 以字節(jié)流讀取但是不讀取為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); // 直接以字節(jié)流的方式輸出到文件 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { in.close(); out.close(); } } /* 將文件以字節(jié)流的方式讀取文件轉(zhuǎn)為String但是又重新將String轉(zhuǎn)為字節(jié)流然后寫入 */ 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"); // 在這里轉(zhuǎn)換的話會(huì)導(dǎo)致都是? 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測(cè)試GBK結(jié)果正確 DOC測(cè)試以UTF-8測(cè)試結(jié)果:拷斤棍 // 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(); } }
項(xiàng)目地址:https://github.com/Somersames...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66904.html
摘要:一面試題及剖析今日面試題今天壹哥帶各位復(fù)習(xí)一塊可能會(huì)令初學(xué)者比較頭疼的內(nèi)容,起碼當(dāng)時(shí)讓我很有些頭疼的內(nèi)容,那就是流。在這里壹哥會(huì)從兩部分展開(kāi)介紹流,即與流。除此之外盡量使用字節(jié)流。關(guān)閉此輸入流并釋放與流相關(guān)聯(lián)的任何系統(tǒng)資源。 一. 面試題及剖析 1. 今日面試題 今天 壹哥 帶各位復(fù)習(xí)一塊可...
摘要:是一個(gè)系統(tǒng)支持的所有字符的集合,包括各國(guó)家文字標(biāo)點(diǎn)符號(hào)圖形符號(hào)數(shù)字等字符集簡(jiǎn)體中文碼表。支持中國(guó)國(guó)內(nèi)少數(shù)民族的文字,同時(shí)支持繁體漢字以及日韓漢字等字符集為表達(dá)任意語(yǔ)言的任意字符而設(shè)計(jì),是業(yè)界的一種標(biāo)準(zhǔn),也稱為統(tǒng)一碼標(biāo)準(zhǔn)萬(wàn)國(guó)碼。 1 File1.1 File類的概述和構(gòu)造方法File: 它是文件和目錄路徑名的抽象...
摘要:在包下主要包括輸入輸出兩種流,每種輸入輸出流又可分為字節(jié)流和字符流兩大類。輸入輸出是從程序運(yùn)行所在的內(nèi)存的角度而言的。的輸入流主要由和作為基類,而輸出流主要由和作為基類。 本章主要參考和摘自瘋狂java講義上面的(java編程思想的后面看過(guò)后有新的內(nèi)容再補(bǔ)充進(jìn)去吧)。 輸入輸出是所有程序都必需的部分————使用輸入機(jī)制允許程序讀取外部數(shù)據(jù)(包括磁盤、光盤等存儲(chǔ)設(shè)備上的數(shù)據(jù)和用戶輸入的...
摘要:大家好,樂(lè)字節(jié)小樂(lè)又來(lái)了。上一篇給大家?guī)?lái)的是中的流之輸入流樂(lè)字節(jié),本文將繼續(xù)講述流之輸出流。一輸出流抽象類和和也非常相似。從上述的字節(jié)數(shù)組中,讀取字符串。 大家好,樂(lè)字節(jié)小樂(lè)又來(lái)了。上一篇給大家?guī)?lái)的是:Java中的IO流之輸入流|樂(lè)字節(jié),本文將繼續(xù)講述IO流之輸出流。showImg(https://segmentfault.com/img/bVbvQx1?w=600&h=338);...
摘要:字符流字符流是什么字符流是可以直接讀寫字符的流字符流讀取字符就要先讀取到字節(jié)數(shù)據(jù)然后轉(zhuǎn)為字符如果要寫出字符需要把字符轉(zhuǎn)為字節(jié)再寫出類的方法可以按照字符大小讀取通過(guò)項(xiàng)目默認(rèn)的碼表一次讀取一個(gè)字符賦值給將讀到的字符強(qiáng)轉(zhuǎn)后打印字符流類的方法可以 1_字符流FileReader 1.字符流是什么 字符流是可以直接讀寫字符的IO流 字符流讀取字符, 就要先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符. ...
閱讀 2022·2021-11-24 09:39
閱讀 1884·2019-08-30 15:55
閱讀 2177·2019-08-30 15:53
閱讀 576·2019-08-29 13:16
閱讀 991·2019-08-26 12:20
閱讀 2390·2019-08-26 11:58
閱讀 3155·2019-08-26 10:19
閱讀 3314·2019-08-23 18:31