Java IO流 文件傳輸基本。本站提示廣大學習愛好者:(Java IO流 文件傳輸基本)文章只能為提供參考,不一定能成為您想要的結果。以下是Java IO流 文件傳輸基本正文
1、文件的編碼
package com.study.io; /** * 測試文件編碼 */ public class EncodeDemo { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String s="好勤學習ABC"; byte[] bytes1=s.getBytes();//這是把字符串轉換成字符數組,轉換成的字節序列用的是項目默許的編碼(這裡為UTF-8) for (byte b : bytes1) { //把字節(轉換成了int)以16進制的方法顯示 System.out.print(Integer.toHexString(b & 0xff)+" ");//& 0xff是為了把後面的24個0去失落只留下後八位 } System.out.println(); /*utf-8編碼中中文占用3個字節,英文占用1個字節*/ byte[] bytes2 = s.getBytes("utf-8");//這裡會有異常展現,我們就throw這個異常 for (byte b : bytes2) { System.out.print(Integer.toHexString(b & 0xff)+" "); } System.out.println(); /*gbk編碼中文占用2個字節,英文占用1個字節*/ byte[] bytes3 = s.getBytes("gbk");//這裡會有異常展現,我們就throw這個異常 for (byte b : bytes3) { System.out.print(Integer.toHexString(b & 0xff)+" "); } System.out.println(); /*utf-16be編碼中文占用2個字節,英文占用2個字節*/ byte[] bytes4 = s.getBytes("utf-16be");//這裡會有異常展現,我們就throw這個異常 for (byte b : bytes4) { System.out.print(Integer.toHexString(b & 0xff)+" "); } System.out.println(); /*當你的字節序列是某種編碼時,這個時刻想把字節序列釀成字符串,也須要用這類編碼方法,不然會湧現亂碼*/ String str1=new String(bytes4);//這時候會應用項目默許的編碼來轉換,能夠湧現亂碼 System.out.println(str1); //要應用字節序列的編碼來停止轉換 String str2=new String(bytes4,"utf-16be"); System.out.println(str2); } }
剖析:
* 1. “& 0xff”的說明:
* 0xFF表現的是16進制(十進制是255),表現為二進制就是“11111111”。
* 那末&符表現的是按位數停止與(同為1的時刻前往1,不然前往0)
* 2.字節byte與int類型轉換:
* Integer.toHexString(b & 0xff)這裡先把byte類型的b和0xff停止了運算,然後Integer.toHexString獲得了十六進制字符串
* 可以看出b & 0xFF運算後得出的依然是個int,那末為什麼要和 0xFF停止與運算呢?直接 Integer.toHexString(b);,將byte強轉為int不可嗎?謎底是不可的.
* 其緣由在於:1.byte的年夜小為8bits而int的年夜小為32bits;2.java的二進制采取的是補碼情勢
* Integer.toHexString的參數是int,假如不停止&0xff,那末當一個byte會轉換成int時,因為int是32位,而byte只要8位這時候會停止補位。。。。。。
* 所以,一個byte跟0xff相預會先將誰人byte轉化成整形運算,如許,成果中的高的24個比特就總會被清0,因而成果老是我們想要的。
* 3.utf-8編碼:中文占用3個字節,英文占用1個字節
* gbk編碼:中文占用2個字節,英文占用1個字節
* Java采取雙字節編碼(就是Java中的一個字符占兩個字節)是utf-16be編碼。中文占用2個字節,英文占用2個字節
*
* 4.當你的字節序列是某種編碼時,這個時刻想把字節序列釀成字符串,也須要用這類編碼方法,不然會湧現亂碼
* 5.文本文件 就是字節序列。可所以隨意率性編碼的字節序列。
* 假如我們在中文機械上直接創立文本文件,那末該文件只熟悉ANSI編碼(例如直接在電腦中創立文本文件)
2、File類的應用
package com.study.io; import java.io.File; /** * File類的應用 */ public class FileDemo { /*java.iO.File類表現文件或目次 File類只用於表現文件或目次的信息(稱號,年夜小等),不克不及用於文件內容的拜訪。*/ public static void main(String[] args) { File file=new File("D:\\111");//創立文件對象時指定目次須要用雙斜槓,由於“\”是本義字符 /*目次的中央的分隔符可以用雙斜槓,也能夠用反斜槓,也能夠用File.separator設置分隔符*/ // File file1=new File("d:"+File.separator); // System.out.println(file.exists());//exists()斷定文件或文件夾能否存在 if(!file.exists()){//假如文件不存在 file.mkdir();//創立文件夾mkdir(),還有mkdirs()創立多級目次 }else{ file.delete();//刪除文件或文件夾 } //斷定能否是一個目次isDirectory,假如是目次前往true,假如不是目次或許目次不存在前往false System.out.println(file.isDirectory()); //斷定能否是一個文件isFile System.out.println(file.isFile()); File file2=new File("D:\\222","123.txt"); //經常使用API: System.out.println(file);//打印的是file.toString()的內容 System.out.println(file.getAbsolutePath());//獲得相對途徑 System.out.println(file.getName());//獲得文件稱號 System.out.println(file2.getName()); System.out.println(file.getParent());//獲得父級相對途徑 System.out.println(file2.getParentFile().getAbsolutePath()); } }
運轉成果:
解釋:
java.iO.File類表現文件或目次
File類只用於表現文件或目次的信息(稱號,年夜小等),不克不及用於文件內容的拜訪。
經常使用的API:
1.創立File對象:File file=new File(String path);留意:File.seperater();獲得體系分隔符,如:“\”.
2.boolean file.exists();能否存在.
3.file.mkdir();或許file.mkdirs();創立目次或多級目次。
4.file.isDirectory()斷定能否是目次
file.isFile()斷定能否是文件。
5.file.delete();刪除文件或目次。
6.file.createNewFile();創立新文件。
7.file.getName()獲得文件稱號或目次相對途徑。
8.file.getAbsolutePath()獲得相對途徑。
9.file.getParent();獲得父級相對途徑。
1、遍歷目次
package com.study.io; import java.io.File; import java.io.IOException; /** * File對象類 * 列出File類的經常使用操作,好比:過濾、遍歷等操作 */ public class FileUtils { /** * 列出指定目次下(包含其子目次)的一切文件 * @param dir * @throws IOException */ public static void listDirectory(File dir) throws IOException{ if(!dir.exists()){//exists()辦法用於斷定文件或目次能否存在 throw new IllegalArgumentException("目次:"+dir+"不存在"); } if(!dir.isDirectory()){//isDirectory()辦法用於斷定File類的對象能否是目次 throw new IllegalArgumentException(dir+"不是目次"); } /*String[] fileNames = dir.list();//list()辦法用於列出以後目次下的子目次和文件(直接是子目次的稱號,不包括子目次下的內容),前往的是字符串數組 for (String string : fileNames) { System.out.println(string); }*/ //假如要遍歷子目次下的內容就須要結構成File對象做遞歸操作,File供給了直接前往File對象的API File[] listFiles = dir.listFiles();//前往的是直接子目次(文件)的籠統 if(listFiles !=null && listFiles.length >0){ for (File file : listFiles) { /*System.out.println(file);*/ if(file.isDirectory()){ //遞歸 listDirectory(file); }else{ System.out.println(file); } } } } }
測試類:
public class FileUtilsTest { public static void main(String[] args) throws IOException { FileUtils.listDirectory(new File("D:\\ioStudy")); } }
運轉成果:
3、RandomAccessFile類的應用
RandomAccessFile:java供給的對文件內容的拜訪,既可以讀文件,也能夠寫文件。
RandomAccessFile支撐隨機拜訪文件,可以拜訪文件的隨意率性地位。
留意 Java文件的模子:
運轉成果:
1
12
[65, 66, 127, -1, -1, -1, 127, -1, -1, -1, -42, -48]
7f
ff
ff
ff
7f
ff
ff
ff
d6
d0
4、字撙節(FileInputStream、FileOutputStream)
IO流可分為輸出流和輸入流。
這裡又可分為字撙節和字符流。
代碼示例:
package com.study.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * IO對象類 * ❤文件輸出輸入流: * FileInputStream-->詳細完成了在文件上讀取數據 * FileOutputStream-->完成了向文件中寫出byte數據的辦法 * ❤數據輸出輸入流: * DataOutputStream / DataInputStream:對"流"功效的擴大,可以加倍方面的讀取int,long,字符等類型數據 * DataOutputStream writeInt()/writeDouble()/writeUTF() * ❤字節緩沖流: * BufferedInputStream & BufferedOutputStream * 這兩個流類位IO供給了帶緩沖區的操作,普通翻開文件停止寫入或讀取操作時,都邑加上緩沖,這類流形式進步了IO的機能 * 好比:從運用法式中把輸出放入文件,相當於將一缸水倒入到另外一個缸中: FileOutputStream--->write()辦法相當於一滴一滴地把水“轉移”曩昔 DataOutputStream-->writeXxx()辦法會便利一些,相當於一瓢一瓢把水“轉移”曩昔 BufferedOutputStream--->write辦法更便利,相當於一瓢一瓢先放入桶中(即緩存區),再從桶中倒入到另外一個缸中,機能進步了 */ public class IOUtil { /** * 讀取指定文件內容,依照16進制輸入到掌握台 * 而且每輸入10個byte換行 * @param fileName * 單字節讀取不合適年夜文件,年夜文件效力很低 */ public static void printHex(String fileName)throws IOException{ //把文件作為字撙節停止都操作 FileInputStream in=new FileInputStream(fileName); int b; int i=1; while((b=in.read())!=-1){ /* 0xff換成2進制就是8個1,如許與的話,其實就是取到了字符的低8位。 * oxf就是15, 小於15的數會轉換成一個16進制數, * 你的代碼裡願望是固定的兩個16進制數,所以當只會發生一個時要加個0*/ if(b <= 0xf){ //單元數後面補0 System.out.print("0"); } //Integer.toHexString(b)將整型b轉換為16進制表現的字符串 System.out.print(Integer.toHexString(b)+" "); if(i++%10==0){ System.out.println(); } } in.close();//文件讀寫完成今後必定要封閉 } /** * 批量讀取,對年夜文件而言效力高,也是我們最經常使用的讀文件的方法 * @param fileName * @throws IOException */ public static void printHexByByteArray(String fileName)throws IOException{ FileInputStream in = new FileInputStream(fileName); byte[] buf = new byte[8 * 1024]; /*從in中批量讀取字節,放入到buf這個字節數組中, * 從第0個地位開端放,最多放buf.length個 * 前往的是讀到的字節的個數 */ /*int bytes = in.read(buf,0,buf.length);//一次性讀完,解釋字節數組足夠年夜 int j = 1; for(int i = 0; i < bytes;i++){ System.out.print(Integer.toHexString(buf[i] & 0xff)+" "); if(j++%10==0){ System.out.println(); } }*/ int bytes = 0; int j = 1; while((bytes = in.read(buf,0,buf.length))!=-1){ for(int i = 0 ; i < bytes;i++){ System.out.print(Integer.toHexString(buf[i] & 0xff)+" "); /** * & 0xff:byte類型8位,int類型32位,為了不數據轉換毛病,經由過程&0xff將高24位清零 */ if(j++%10==0){ System.out.println(); } } } in.close(); } /** * 文件拷貝,字節批量讀取 * @param srcFile * @param destFile * @throws IOException */ public static void copyFile(File srcFile, File destFile) throws IOException { if (!srcFile.exists()) { throw new IllegalArgumentException("文件:" + srcFile + "不存在"); } if (!srcFile.isFile()) { throw new IllegalArgumentException(srcFile + "不是文件"); } FileInputStream in = new FileInputStream(srcFile); FileOutputStream out = new FileOutputStream(destFile);//文件不存在時,會直接創立;假如存在,刪除後建 byte[] buf = new byte[8 * 1024];//批量讀寫 int b; while ((b = in.read(buf, 0, buf.length)) != -1) {//read(buf,0,buf.length)帶參數的read前往的是字節的總長度;當全體讀完後前往的是-1; out.write(buf, 0, b); out.flush();// 最好加上 } in.close(); out.close(); } /** * 停止文件的拷貝,應用帶緩沖的字撙節 * @param srcFile * @param destFile * @throws IOException */ public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{ if(!srcFile.exists()){ throw new IllegalArgumentException("文件:"+srcFile+"不存在"); } if(!srcFile.isFile()){ throw new IllegalArgumentException(srcFile+"不是文件"); } BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); int c ; while((c = bis.read())!=-1){ bos.write(c); bos.flush();//刷新緩沖區 } bis.close(); bos.close(); } /** * 單字節,不帶緩沖停止文件拷貝 * @param srcFile * @param destFile * @throws IOException */ public static void copyFileByByte(File srcFile,File destFile)throws IOException{ if(!srcFile.exists()){ throw new IllegalArgumentException("文件:"+srcFile+"不存在"); } if(!srcFile.isFile()){ throw new IllegalArgumentException(srcFile+"不是文件"); } FileInputStream in = new FileInputStream(srcFile); FileOutputStream out = new FileOutputStream(destFile); int c ; while((c = in.read())!=-1){//read()不帶參數的read前往的是讀到的字節內容;當全體讀完後前往的都是是-1; out.write(c); out.flush(); } in.close(); out.close(); } }
測試類:
package com.study.io; import java.io.File; import java.io.IOException; import org.junit.Test; public class IOUtilTest { @Test public void testPrintHex() { try { IOUtil.printHex("D:\\Javaio\\FileUtils.java"); } catch (IOException e) { e.printStackTrace(); } } @Test public void testPrintHexByByteArray() { try { long start = System.currentTimeMillis();//以後時光與調和世界時 1970 年 1 月 1 日午夜之間的時光差(以毫秒為單元丈量) //IOUtil.printHexByByteArray("e:\\javaio\\FileUtils.java"); //IOUtil.printHex("e:\\javaio\\1.mp3"); IOUtil.printHexByByteArray("e:\\javaio\\1.mp3"); System.out.println(); long end = System.currentTimeMillis(); System.out.println(end - start); } catch (IOException e) { e.printStackTrace(); } } @Test public void testCopyFile(){ try { IOUtil.copyFile(new File("d:\\javaio\\1.txt"), new File("d:\\javaio\\1copy.txt")); } catch (IOException e) { e.printStackTrace(); } } @Test public void testCopyFileByBuffer(){ try { long start = System.currentTimeMillis(); /*IOUtil.copyFileByByte(new File("e:\\javaio\\1.mp3"), new File( "e:\\javaio\\2.mp3"));*/ //兩萬多毫秒 /*IOUtil.copyFileByBuffer(new File("e:\\javaio\\1.mp3"), new File( "e:\\javaio\\3.mp3"));//一萬多毫秒*/ IOUtil.copyFile(new File("e:\\javaio\\1.mp3"), new File( "e:\\javaio\\4.mp3"));//7毫秒 long end = System.currentTimeMillis(); System.out.println(end - start ); } catch (IOException e) { e.printStackTrace(); } } }
5、字符流
package com.study.io; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class IsrAndOswDemo { public static void main(String[] args)throws IOException { FileInputStream in = new FileInputStream("e:\\javaio\\utf8.txt"); InputStreamReader isr = new InputStreamReader(in,"utf-8");//默許項目標編碼,操作的時刻,要寫文件自己的編碼格局 FileOutputStream out = new FileOutputStream("e:\\javaio\\utf81.txt"); OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8"); /*int c ; while((c = isr.read())!=-1){ System.out.print((char)c); }*/ char[] buffer = new char[8*1024]; int c; /*批量讀取,放入buffer這個字符數組,從第0個地位開端放置,最多放buffer.length個前往的是讀到的字符的個數*/ while(( c = isr.read(buffer,0,buffer.length))!=-1){ String s = new String(buffer,0,c); System.out.print(s); osw.write(buffer,0,c); osw.flush(); } isr.close(); osw.close(); } }
字符流之文件讀寫流(FileReader/FileWriter)
字符流的過濾器
6、對象的序列化和反序列化
示例:
留意: