Java IO流學(xué)習(xí)總結(jié)之文件傳輸基礎(chǔ)
一、Java IO流總覽
二、File類
2.1 常用API
package pkg1; import java.io.File; import java.io.IOException; /** * @author Administrator * @date 2021/4/2 */ public class FileDemo { public static void main(String[] args) { // 了解構(gòu)造函數(shù),可查看API File file = new File("d:\\javaio\\cook"); // 設(shè)置分隔符,不同系統(tǒng)也可以認(rèn)識 //File file=new File("d:"+File.separator); //System.out.println(file.exists()); if (!file.exists()) { file.mkdirs(); } else { file.delete(); } // 是否是一個目錄,如果是目錄返回true,如果不是目錄或目錄不存在返回false System.out.println(file.isDirectory()); // 如果是一個文件 System.out.println(file.isFile()); //File file2 = new File("d:\\javaio\\日記1.txt"); File file2 = new File("d:\\javaio", "日記1.txt"); if (!file2.exists()) { try { file2.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } else { file2.delete(); } // 常用File對象的api System.out.println(file);// file.toString()的內(nèi)容 System.out.println(file.getAbsolutePath()); System.out.println(file.getName()); System.out.println(file2.getName()); System.out.println(file.getParent()); System.out.println(file2.getParent()); System.out.println(file.getParentFile().getAbsolutePath()); } }
測試結(jié)果:
其他API:
package pkg1; import java.io.*; import java.util.RandomAccess; /** * @author Administrator * @date 2021/4/7 */ class FileDemo2 { public static void main(String[] args) { File file = new File("d:\\javaio\\example"); if (!file.exists()) { file.mkdir(); } /*String[] fileNames = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { System.out.println("文件是:"+dir + "\\" + name); return name.endsWith("java"); } }); for (String fileName : fileNames != null ? fileNames : new String[0]) { System.out.println(fileName); }*/ /*File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { System.out.println("文件是:" + dir + "\\" + name); return false; } }); for (File fileName : files) { System.out.println(fileName.toString()); }*/ File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { System.out.println(pathname); return false; } }); for (File fileName : files) { System.out.println(fileName.toString()); } } }
測試:
2.2 遍歷目錄
package pkg2; import java.io.File; /** * 列出File的一些常用操作,如過濾、遍歷 */ public class FileUtils { /** * 列出指定目錄(包括其子目錄)下的所有文件 */ public static void listDirectory(File dir) throws IllegalAccessException { if (!dir.exists()) { throw new IllegalArgumentException("目錄:" + dir + "不存在"); } if (!dir.isDirectory()) { throw new IllegalArgumentException(dir + "不存在"); } // list()用于列出當(dāng)前目錄下的子目錄(不包含子目錄下的內(nèi)容)和文件。返回的是字符串?dāng)?shù)組。 /*String[] fileNames = dir.list(); for (String string : fileNames) { System.out.println(dir + "\\" + string); }*/ // 若要遍歷子目錄下的內(nèi)容,就要構(gòu)造成File對象進(jìn)行遞歸操作。File提供了直接返回File對象的API File[] files = dir.listFiles();//返回直接子目錄(文件)的抽象 /*for (File file : files) { System.out.println(file); }*/ if (files != null && files.length > 0) { for (File file : files) { if (file.isDirectory()) { // 遞歸 listDirectory(file); } else { System.out.println(file); } } } } }
測試類:
package pkg2; import java.io.File; public class FileUtilsTest { public static void main(String[] args) throws IllegalAccessException { FileUtils.listDirectory(new File("d:javaio")); } }
測試結(jié)果:
三、RandomAccessFile類
package pkg3; import java.io.*; import java.util.Arrays; public class RafDemo { public static void main(String[] args) throws IOException { // 若沒有指定路徑,則表示相對路徑,即項目所在路徑。 File demo = new File("demo"); if (!demo.exists()) { demo.mkdir(); } File file = new File(demo, "raf.dat"); if (!file.exists()) { file.createNewFile(); } RandomAccessFile raf = new RandomAccessFile(file, "rw"); // 查看指針位置 System.out.println(raf.getFilePointer());// 0 raf.writeInt('A');// 只寫了一個字節(jié) System.out.println(raf.getFilePointer()); raf.writeInt('B'); int i = 0x7fffffff; // 用write方法每次只能寫一個字節(jié),如果要把i寫進(jìn)去就要寫4次 raf.writeInt(i >>> 24);//高8位 raf.writeInt(i >>> 16); raf.writeInt(i >>> 8); raf.writeInt(i);// 低8位 System.out.println(raf.getFilePointer()); // 直接寫一個int ,與上述4步操作等效 raf.writeInt(i); String s = "中"; byte[] gbk = s.getBytes("gbk"); raf.write(gbk); System.out.println("raf長度:" + raf.length()); // 讀文件,必須把指針移到頭部 raf.seek(0); // 一次性讀取,把文件中的內(nèi)容都讀到字節(jié)數(shù)組匯總 byte[] buf = new byte[(int) raf.length()]; raf.read(buf); System.out.println(Arrays.toString(buf)); // 轉(zhuǎn)為字符串 /*String s1=new String(buf,"utf-8"); System.out.println(s1);*/ for (byte b : buf) { System.out.print(Integer.toHexString(b & 0xff) + " "); } raf.close(); } }
測試結(jié)果:
四、字節(jié)流
4.1 FileInputStream
package pkg4; import java.io.*; public class IOUtil { /** * 讀取指定文件內(nèi)容, 按照十六進(jìn)制輸出到控制臺, * 且每輸出10個byte換行 * * @param fileName */ public static void printHex(String fileName) throws IOException { // 把文件作為字節(jié)流進(jìn)行操作 FileInputStream fis = new FileInputStream(fileName); int b; int i = 1; while ((b = fis.read()) != -1) { if (b <= 0xf) { // 單位數(shù)前補0 System.out.print("0"); } // 將整型b轉(zhuǎn)換為16進(jìn)制表示的字符串 System.out.print(Integer.toHexString(b) + " "); if (i++ % 10 == 0) { System.out.println(); } } fis.close(); } public static void printHexByByteArray(String fileName) throws IOException { FileInputStream fis = new FileInputStream(fileName); /*byte[] buf = new byte[20 * 1024]; //從fis中批量讀取字節(jié),放入到buf字節(jié)數(shù)組中,從第0個位置開始放,最多放buf.length個,返回的是讀到的字節(jié)個數(shù) int bytes = fis.read(buf, 0, buf.length);// 一次性讀完,說明字節(jié)數(shù)組足夠大 int j = 1; for (int i = 0; i < bytes; i++) { if (buf[i] <= 0xf) { System.out.print("0"); } System.out.println(Integer.toHexString(buf[i]) + " "); if (j++ % 10 == 0) { System.out.println(); } }*/ // 當(dāng)字節(jié)數(shù)組容量不夠,一次讀不完時 byte[] buf = new byte[8 * 1024]; int bytes = 0; int j = 1; while ((bytes = fis.read(buf, 0, buf.length)) != -1) { for (int i = 0; i < bytes; i++) { // byte是8位,int類型是32位,為了避免數(shù)據(jù)轉(zhuǎn)換錯誤,通過&0xff將高24位清零 System.out.print(Integer.toHexString(buf[i] & 0xff) + " "); if (j++ % 10 == 0) { System.out.println(); } } } fis.close(); } /** * 文件拷貝操作 -> 字節(jié)批量讀取式拷貝,效率最優(yōu) */ 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 fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile); byte[] buf = new byte[8 * 1024]; int b; while ((b = fis.read(buf, 0, buf.length)) != -1) { fos.write(buf, 0, b); fos.flush();//最好加上這個 } fis.close(); fos.close(); } /** * 用帶緩沖的字節(jié)流,進(jìn)行文件拷貝,效率居中 */ 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); // 刷新緩沖區(qū)。不能省略,否則無法寫入 bos.flush(); } bis.close(); bos.close(); } /** * 文件拷貝操作 -> 單字節(jié),不帶緩沖式拷貝,效率最差 */ 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 fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile); int b; while ((b = fis.read()) != -1) { fos.write(b); fos.flush(); } fis.close(); fos.close(); } }
測試類:
package pkg4; import java.io.IOException; public class IOUtilTest1 { public static void main(String[] args) { try { IOUtil.printHex("d:\\javaio\\FileUtils.java"); } catch (IOException e) { e.printStackTrace(); } } }
4.2 FileOutputStream
package pkg5; import pkg4.IOUtil; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutDemo { public static void main(String[] args) throws IOException { // 如果該文件不存在,則直接創(chuàng)建,如果存在,則刪除后創(chuàng)建。若要在后面追加內(nèi)容,參數(shù)中加一個true FileOutputStream fos = new FileOutputStream("demo/out.dat"); // 寫入A的低8位 fos.write('A'); fos.write('B'); // write只能寫8位,那么寫一個int需要4次,每次8位 int a = 10; fos.write(a >>> 24); fos.write(a >>> 16); fos.write(a >>> 8); fos.write(a); byte[] gbk = "中國".getBytes("gbk"); fos.write(gbk); fos.close(); IOUtil.printHex("demo/out.dat"); } }
測試類:
package pkg5; import pkg4.IOUtil; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; public class IOUtilTest3 { public static void main(String[] args) { try { IOUtil.copyFile(new File("d:\\javaio\\abc.txt"), new File("d:\\javaio\\abc1.txt")); } catch (IOException e) { e.printStackTrace(); } } }
4.3 DataInputStream 、DataOutputStream
輸入流:
package pkg6; import pkg4.IOUtil; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; public class DisDemo { public static void main(String[] args) throws IOException { String file = "demo/dos.dat"; IOUtil.printHex(file); DataInputStream dis = new DataInputStream(new FileInputStream(file)); int i = dis.readInt(); System.out.println(i); i = dis.readInt(); System.out.println(i); long l = dis.readLong(); System.out.println(l); double d = dis.readDouble(); System.out.println(d); String s = dis.readUTF(); System.out.println(s); dis.close(); } }
輸出流:
package pkg6; import pkg4.IOUtil; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class DosDemo { public static void main(String[] args) throws IOException { String file = "demo/dos.dat"; DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)); dos.writeInt(10); dos.writeInt(-10); dos.writeLong(10l); dos.writeDouble(10.5); // 采用utf-8寫入 dos.writeUTF("中國"); // 采用utf-16be寫入 dos.writeChars("中國"); dos.close(); IOUtil.printHex(file); } }
4.4 字節(jié)緩沖流
工具類在4.1小節(jié)的IOUtil.java中。
測試類:
package pkg7; import pkg4.IOUtil; import java.io.File; import java.io.IOException; public class IOUtilTest4 { public static void main(String[] args) { // 效率最高 try { long start = System.currentTimeMillis(); IOUtil.copyFile(new File("d:\\javaio\\Alpha.mp3"), new File("d:\\javaio\\Alpha1.mp3")); long end = System.currentTimeMillis(); System.out.println("耗時1:" + (end - start)); } catch (IOException e) { e.printStackTrace(); } // 效率居中 try { long start = System.currentTimeMillis(); IOUtil.copyFileByBuffer(new File("d:\\javaio\\Alpha.mp3"), new File("d:\\javaio\\Alpha2.mp3")); long end = System.currentTimeMillis(); System.out.println("耗時2:" + (end - start)); } catch (IOException e) { e.printStackTrace(); } // 效率最差 try { long start = System.currentTimeMillis(); IOUtil.copyFileByByte(new File("d:\\javaio\\Alpha.mp3"), new File("d:\\javaio\\Alpha3.mp3")); long end = System.currentTimeMillis(); System.out.println("耗時3:" + (end - start)); } catch (IOException e) { e.printStackTrace(); } } }
五、字符流
5.1 InputStreamReader、OutputStreamWriter
package pkg8; import java.io.*; public class IsrAndOswDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("d:\\javaio\\aa.txt"); InputStreamReader isr = new InputStreamReader(fis);//未指定編碼格式,即按照項目默認(rèn)編碼操作 FileOutputStream fos = new FileOutputStream("d:\\javaio\\aa.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos);//未指定編碼格式,即按照項目默認(rèn)編碼操作 /*int c; while ((c=isr.read())!=-1){ System.out.print((char)c); }*/ /* 批量讀取。 放入buffer這個字節(jié)數(shù)組,從第0個位置開始放,最多放buffer.length個,返回讀到的字符個數(shù)。 */ char[] buffer = new char[8 * 1024]; int c; 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(); } }
5.2 FileReader、FileWriter
package pkg8; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FrAndFwDemo { /** * 注意:FileReader、FileWriter不能指定編碼方式 */ public static void main(String[] args) throws IOException { FileReader fr = new FileReader("d:\\javaio\\aa.txt"); // 指定參數(shù),也可以追加內(nèi)容:FileWriter(String fileName, boolean append) FileWriter fw = new FileWriter("d:\\javaio\\bb.txt"); char[] buffer = new char[8 * 1024]; int c; while ((c = fr.read(buffer, 0, buffer.length)) != -1) { fw.write(buffer, 0, c); fw.flush(); } fr.close(); fw.close(); } }
5.3 BufferedReader、BufferedWriter、PrintWriter
package pkg9; import java.io.*; public class BrAndBwOrPwDemo { public static void main(String[] args) throws IOException { // 對文件進(jìn)行讀寫操作 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\javaio\\aa.txt"))); //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\javaio\\cc.txt"))); // PrintWriter可以替換BufferedWriter PrintWriter pw = new PrintWriter("d:\\javaio\\cc.txt"); String line; while ((line = br.readLine()) != null) { // 一次讀一行,不能識別換行 System.out.println(line); /*bw.write(line); // 手動給出換行 bw.newLine(); bw.flush();*/ pw.println(line); pw.flush(); } br.close(); //bw.close(); pw.close(); } }
六、對象的序列化、反序列化
6.1 transient關(guān)鍵字、序列化、反序列化
實體類:
package pkg10; import java.io.Serializable; public class Student implements Serializable { private String stuNo; private String stuName; // 該元素不會 進(jìn)行JVM默認(rèn)的序列化,但可以手動序列化 private transient int stuAge; public Student(String stuNo, String stuName, int stuAge) { this.stuNo = stuNo; this.stuName = stuName; this.stuAge = stuAge; } public String getStuNo() { return stuNo; } public void setStuNo(String stuNo) { this.stuNo = stuNo; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getStuAge() { return stuAge; } public void setStuAge(int stuAge) { this.stuAge = stuAge; } @Override public String toString() { return "Student{" + "stuNo='" + stuNo + '\'' + ", stuName='" + stuName + '\'' + ", stuAge=" + stuAge + '}'; } /** * 序列化 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // 把JVM能默認(rèn)序列化的元素進(jìn)行序列化操作 s.defaultWriteObject(); // 手動完成stuAge的序列化 s.writeInt(stuAge); } /** * 反序列化 */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // 把JVM默認(rèn)能反序列化的元素進(jìn)行反序列化操作 s.defaultReadObject(); // 手動完成stuAge的反序列化 stuAge = s.readInt(); } }
測試類:
package pkg10; import java.io.*; import java.util.ArrayList; public class ObjectSeriaDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { String file = "demo/obj.dat"; // 1、對象的序列化 /*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); Student student = new Student("10001", "張三", 20); oos.writeObject(student); oos.flush(); oos.close();*/ // 2、對象的反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); Student stu = (Student) ois.readObject(); System.out.println(stu); ois.close(); } }
6.2 序列化、反序列化時,子類、父類構(gòu)造方法的調(diào)用
package pkg11; import java.io.*; import java.sql.SQLOutput; public class ObjectSeriaDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { // 序列化 /*ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("demo/obj1.dat")); Foo2 foo2=new Foo2(); oos.writeObject(foo2); oos.flush(); oos.close();*/ // 反序列化 /*ObjectInputStream ois=new ObjectInputStream(new FileInputStream("demo/obj1.dat")); Foo2 foo2= (Foo2) ois.readObject(); System.out.println(foo2); ois.close();*/ /*ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("demo/obj1.dat")); Bar2 bar2=new Bar2(); oos.writeObject(bar2); oos.flush(); oos.close();*/ /*ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo/obj1.dat")); Bar2 bar2 = (Bar2) ois.readObject(); System.out.println(bar2); ois.close();*/ /*ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("demo/obj1.dat")); Ccc2 ccc2=new Ccc2(); oos.writeObject(ccc2); oos.flush(); oos.close();*/ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("demo/obj1.dat")); Ccc2 ccc2 = (Ccc2) ois.readObject(); System.out.println(ccc2); ois.close(); } } /** * 一個類實現(xiàn)了序列化接口,其子類都可以實現(xiàn)序列化。 */ class Foo implements Serializable { public Foo() { System.out.println("foo..."); } } class Foo1 extends Foo { public Foo1() { System.out.println("foo1..."); } } class Foo2 extends Foo1 { public Foo2() { System.out.println("foo2..."); } } /** * 對子類對象進(jìn)行反序列化操作時, * 如果其父類沒有實現(xiàn)序列化接口 * 那么其父類的構(gòu)造函數(shù)會被調(diào)用 */ class Bar { public Bar() { System.out.println("Bar..."); } } class Bar1 extends Bar implements Serializable { public Bar1() { System.out.println("Bar1..."); } } class Bar2 extends Bar1 { public Bar2() { System.out.println("Bar2..."); } } class Ccc { public Ccc() { System.out.println("Ccc..."); } } class Ccc1 extends Ccc { public Ccc1() { System.out.println("Ccc1..."); } } class Ccc2 extends Ccc1 implements Serializable { public Ccc2() { System.out.println("Ccc2..."); } }
Foo2類反序列化時不打印構(gòu)造方法:
Bar2類反序列化時打印了Bar的構(gòu)造方法:
Ccc2類反序列化時打印了Ccc、Ccc1的構(gòu)造方法:
結(jié)論(詳見導(dǎo)圖標(biāo)紅部分):
對子類對象進(jìn)行反序列化操作時,如果其父類沒有實現(xiàn)序列化接口,那么其父類的構(gòu)造函數(shù)會被調(diào)用。
到此這篇關(guān)于Java IO流學(xué)習(xí)總結(jié)之文件傳輸基礎(chǔ)的文章就介紹到這了,更多相關(guān)Java IO流文件傳輸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中配置多數(shù)據(jù)源的方法詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot中配置多數(shù)據(jù)源的方法的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02詳解Java中NullPointerException異常的原因和解決辦法
本文主要介紹了詳解Java中NullPointerException異常的原因和解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07詳解spring Boot 集成 Thymeleaf模板引擎實例
本篇文章主要介紹了spring Boot 集成 Thymeleaf模板引擎實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09基于Spring的Maven項目實現(xiàn)發(fā)送郵件功能的示例
這篇文章主要介紹了基于Spring的Maven項目實現(xiàn)發(fā)送郵件功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03