1.io流簡介
不論是Reader,Writer,還是InputStream,OutputStream,在創建相應的對象是只是創建了相應的映射,相當於修了一條馬路通向兩個位置,但是本身並不參與數據的傳輸,數據的傳輸是通過數組完成的,這個傳輸的過程是單向的(nio的buffer是雙向的)面向於流的傳輸(nio面向緩存數據塊),對於讀的時候不論基於單個字符還是基於數組,當沒有可讀的元素的時候返回值都是-1,有可讀的時候返回的是有效數據的字節或字符長度,返回字符串的時候,在沒有的情況下為null,對於一個輸入流來說具有skip的方法,跳到我們制定的地方去開始輸入,對於寫我們可以設置為true在尾部添加,對於覆蓋數據我們可以是用RandomAccessFile的seek設定覆蓋的位置,對於我們對象流(序列化流)可以將一個文件保存在一個文件中,然后在另一個地方讀取(讀取的前提條件是相應的序列化類需要已經加載到JVM中),對於BufferedOutputStream等采用裝飾模式,也就是在FileOutputStream外面包了一層,對於文件的亂碼問題前面有一篇有介紹。
2.file
public class CreateFile { // 創建文件 public static void creatFile(String filePath) throws Exception { File file = new File(filePath); if (!file.exists()) { file.createNewFile(); } else { System.err.println("文件夾以及存在"); } } // 創建文件夾 public static void creatFolder(String filePath) { File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } else { System.err.println("文件夾以及存在"); } } // 在指定的文件下搜索文件(可以模糊查找) public static List<String> FuzzySearch(String filePath, String regex) { LinkedList<String> lls = new LinkedList<>(); regex = ".*" + regex + ".*"; File file = new File(filePath); if (!file.exists()) { System.err.println("指定的目錄不存在"); return null; } if (!file.isDirectory()) { System.err.println("指定的不是目錄"); return null; } getErgodicFiles(regex, lls, file); if (lls.size() == 0) { System.out.println("沒有找到符合的信息"); } return lls; } // 遍歷文件 public static void getErgodicFiles(String regex, LinkedList<String> lls, File file) { if (file.isDirectory()) { File[] lfs = file.listFiles(); for (File f : lfs) { if (!f.isDirectory()) { String absolutePath = f.getAbsolutePath(); if (absolutePath.matches(regex)) { lls.add(absolutePath); } } else { getErgodicFiles(regex, lls, f); } } } } // 遍歷文件 public static void getErgodicFiles(String fileName, File file) { if (file.isDirectory()) { File[] lfs = file.listFiles(); for (File f : lfs) { if (!f.isDirectory()) { f.delete(); } else { getErgodicFiles(fileName, f); } } } } public static void delete(String fileName) { File file = getFile(fileName); if (file == null) { return; } if (!file.isDirectory()) { file.delete(); return; } getErgodicFiles(fileName, file); file.delete(); System.out.println("刪除成功"); } // 設置文件只讀,但是可以另存為 public static void setOnlyRead(String fileName) { File file = getFile(fileName); if (file == null) { return; } file.setReadable(true); file.setWritable(false); } private static File getFile(String fileName) { File file = new File(fileName); if (!file.exists()) { System.err.println("指定的目錄或者文件夾不存在不存在"); return null; } return file; } public static void main(String[] args) throws Exception { // CreateFile.creatFile("F:/test/file"); // CreateFile.creatFolder("F:/test/file1.txt"); // List<String> fuzzySearch = CreateFile.FuzzySearch("F:/test", "file"); // System.out.println(fuzzySearch); // CreateFile.delete("F:/test/file1.txt"); // CreateFile.setOnlyRead("F:/test/file1/file.txt"); } }
3.new FileOutputStream與 new RandomAccessFile的區別
一個存在則新建,一個存在則覆蓋覆蓋,默認的seek是從0開始的,RandomAccessFile對同一文件可進行讀寫
4.更改某一個文件中的值然后保存
public static void main(String[] args) { try { InputStream resourceAsStream4 = PopertiesDemo1.class.getClassLoader() .getResourceAsStream("cn/collection/demo/config.properties"); Properties properties = new Properties(); properties.load(resourceAsStream4); System.out.println(properties.getProperty("name")); properties.setProperty("name", "李四"); System.out.println(properties.getProperty("name")); FileWriter fileWriter = new FileWriter("config1"); // "aa" 描述信息 properties.store(fileWriter, "aa"); fileWriter.close(); } catch (Exception e) { System.out.println("沒有找到文件"); } }
5.對象流
實現Externalizable接口,Externalizable繼承了Serializable 接口,Externalizable中有兩個方法需要重寫writeExternal及readExternal,在writeObject和readObject時會調用相應的方法。
transient關鍵字表示瞬態的,在保存的是是后不會被保存進對象流,假如我么依舊添加,那么可以使用如下方法
public class Person implements Serializable { private String adress; // transient 關鍵字 表示瞬態 假如需要保存這個那么需要單獨的去保存 private transient int age; private static String name; private transient static int id; public String getAdress() { return adress; } public void setAdress(String adress) { this.adress = adress; } public static int getId() { return id; } public void setId(int id) { this.id = id; } public Person() { super(); } public Person(int age, String adress, int id, String name) { super(); this.age = age; this.adress = adress; this.id = id; this.name = name; } public static String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } // 一定要為私有才可以被調用 private void writeObject(ObjectOutputStream stream) throws IOException { // 將非靜態的非瞬態的保存在對象流中 stream.defaultWriteObject(); stream.writeObject(age); stream.close(); } // 一定要為私有才可以被調用 private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
stream.defaultReadObject(); age = (int) (stream.readObject()); stream.close(); } @Override public String toString() { return "Person [age=" + age + ", adress=" + adress + ",name=" + name + ",id=" + id + "]"; } }
6.分段讀取文件,每次只保存一部分(網絡版的在爬蟲中)
public class SegmentedReadFile extends Thread { private volatile boolean flag = false; @Override public void run() { try { Scanner scanner = new Scanner(System.in); String nextLine = scanner.nextLine(); if (nextLine.equals("true")) { this.flag = true; } } catch (Exception e) { } } public boolean test(String src, String target) throws IOException { File file = new File(src); File file2 = new File(target); // 這里以單個文件為例 if (file.isDirectory()) { System.out.println("該路徑是文件夾不是文件"); return false; } if (!file.isFile()) { System.out.println("該文件路徑不存在"); return false; } if (!file2.isFile()) { try { file2.createNewFile(); } catch (IOException e) { return false; } } FileInputStream fileInputStream=null; BufferedInputStream bufferedInputStream=null; FileOutputStream fileOutputStream=null; BufferedOutputStream bufferedOutputStream=null; if (file2.isFile()) { long lg1 = file.length(); int segment = 24000000; fileInputStream = new FileInputStream(file); bufferedInputStream = new BufferedInputStream(fileInputStream); fileOutputStream = new FileOutputStream(file2, true); bufferedOutputStream = new BufferedOutputStream(fileOutputStream); byte[] bys = new byte[1024]; if (file.length() - file2.length() >= segment) { long lg = file2.length(); bufferedInputStream.skip(lg); for (int i = 0; i <= segment / 1024; i++) { if (flag) { break; }
bufferedInputStream.read(bys); if (i < segment / 1024 ) { bufferedOutputStream.write(bys, 0, 1024); } else { bufferedOutputStream.write(bys, 0, segment%1024); } } } else if(file.length() - file2.length()>0){ long lg = file2.length(); bufferedInputStream.skip(lg); long lastSize=file.length() - file2.length(); for (int i = 0; i <= lastSize / 1024; i++) { if (flag) { break; } int read = bufferedInputStream.read(bys); if (read != -1) { bufferedOutputStream.write(bys, 0, read); } } }else{ System.out.println("傳輸完成"); } } bufferedInputStream.close(); bufferedOutputStream.close(); System.gc(); System.runFinalization(); return true; } public static void main(String[] args) throws IOException { SegmentedReadFile segmentedReadFile = new SegmentedReadFile(); segmentedReadFile.setDaemon(true); segmentedReadFile.start(); boolean test = segmentedReadFile.test("G:/360安全瀏覽器下載安裝包/tim_pc.exe", "G:/360安全瀏覽器下載安裝包/tim_pc1.exe"); if (!test) { System.out.println("傳輸失敗"); } } }
7.重定向輸出記錄錯誤日志文件
public class Redirect1 { public static void main(String[] args) throws FileNotFoundException { String str="hello world"; PrintStream printStream = new PrintStream("y.txt");
//可以不關閉,自動會刷新緩存 printStream.print(str); }
8.字節字符轉換流
public static void main(String[] args) throws IOException { //方式一 FileInputStream fileInputStream = new FileInputStream("1.txt"); //不亂碼的前提是知道編碼,或者是unicode碼的\\u方式寫的 InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); //java內存中是使用unicode碼保存的 String readLine = bufferedReader.readLine(); System.out.println(readLine); if(bufferedReader!=null){ bufferedReader.close(); } if(inputStreamReader!=null){ inputStreamReader.close(); } if(fileInputStream!=null){ fileInputStream.close(); } FileOutputStream fileOutputStream = new FileOutputStream("3.txt"); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"gbk"); BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter); bufferedWriter.write(readLine); if(bufferedWriter!=null){ bufferedWriter.close(); } if(outputStreamWriter!=null){ outputStreamWriter.close(); } if(fileOutputStream!=null){ fileOutputStream.close(); } FileInputStream fileInputStream1 = new FileInputStream("3.txt"); //按指定解碼然后按unicode保存 InputStreamReader inputStreamReader1 = new InputStreamReader(fileInputStream1,"gbk"); BufferedReader bufferedReader1 = new BufferedReader(inputStreamReader1); String readLine1 = bufferedReader1.readLine(); //將unicode碼有轉換成了工作空間相應的編碼 System.out.println(readLine1); if(bufferedReader1!=null){ bufferedReader1.close(); } if(inputStreamReader1!=null){ inputStreamReader1.close(); } if(fileInputStream1!=null){ fileInputStream1.close(); } //方式二 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byteArrayOutputStream.write(readLine1.getBytes()); //因為我的工作空間是utf-8的 String string = byteArrayOutputStream.toString("utf-8"); byteArrayOutputStream.close(); System.out.println(string); FileInputStream fileInputStream2 = new FileInputStream("3.txt"); ByteArrayOutputStream byteArrayOutputStream2 = new ByteArrayOutputStream(); byte [] bs =new byte [1024]; int len =0; while((len=fileInputStream2.read(bs))!=-1){ byteArrayOutputStream2.write(bs, 0, len); } //不會亂碼 String string2 = byteArrayOutputStream2.toString("gbk"); fileInputStream2.close(); byteArrayOutputStream2.close(); System.out.println(string2); //readLine.getBytes(charset) //Charset.forName("UTF-8").encode(str) }
9.其他一些流
SequenceInputStream 合並多個流文件 SequenceInputStream(Enumeration<? extends InputStream> e)
PrintWriter 與 PrintStream 差不多
PipedWriter 是向與其它線程共用的管道中寫入數據
CharArrayWriter、StringWriter 是兩種基本的介質流,它們分別向Char 數組、String 中寫入數據
DataOutputStream 保存相應的數據,按保存的順序讀取
ZipOutputStream 壓縮流 批量壓縮(文件夾)可以使用這個方法putNextEntry(ZipEntry e),
ZipEntry(String name)
使用指定名稱創建新的 ZIP 條目。
ZipInputStream 解壓流
public class ZipInputStreamDemo2 { public static void main(String[] args) throws IOException { File file = new File("d:" + File.separator + "zipFile.zip"); File outFile = null; ZipFile zipFile = new ZipFile(file); ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file)); ZipEntry entry = null; InputStream input = null; OutputStream output = null; while ((entry = zipInput.getNextEntry()) != null) { System.out.println("解壓縮" + entry.getName() + "文件"); outFile = new File("d:" + File.separator + entry.getName()); if (!outFile.getParentFile().exists()) { outFile.getParentFile().mkdir(); } if (!outFile.exists()) { outFile.createNewFile(); } input = zipFile.getInputStream(entry); output = new FileOutputStream(outFile); int temp = 0; while ((temp = input.read()) != -1) { output.write(temp); } input.close(); output.close(); } } }
//多個文件進行壓縮
public class ZipOutputStreamDemo2 { public static void main(String[] args) throws IOException { // 要被壓縮的文件夾 File file = new File("d:" + File.separator + "temp"); File zipFile = new File("d:" + File.separator + "zipFile.zip"); InputStream input = null; ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile)); zipOut.setComment("hello"); if (file.isDirectory()) { File[] files = file.listFiles(); for (int i = 0; i < files.length; ++i) { input = new FileInputStream(files[i]); zipOut.putNextEntry(new ZipEntry(file.getName() + File.separator + files[i].getName())); int temp = 0; while ((temp = input.read()) != -1) { zipOut.write(temp); } input.close(); } } } }