IO数据操作的两大体系
1.字符流操作:适合纯文本数据操作
源:Reader
目的:Writer
2.字节流操作:适合所有,常文本以外
源:InputStream
目的:OutputStream
转换流:字符流是从字节流中分出来针对文本文件处理的,如果没有字符流,就不需要转换,可见,转换流应该属于字符流体系
源:InputStreamReader
目的:OutputStreamWriter
应用
1.文本文件复制
思路:
源:InputStream Reader
文本?是!=>Reader
设备:硬盘,文件,=>FileReader
需要缓冲吗?需要!=>BufferedReader
目的:OutputStream Writer
文本?是!=>Writer
设备:硬盘,文件,=>FileWriter
需要缓冲吗?需要!=>BufferedWriter
Demo:不带缓冲与带缓冲
1 package io; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 /** 10 * 将E:\Test\1.txt复制到E:Test1.txt 11 * 12 */ 13 public class CopyTxt { 14 15 public static void main(String[] args) throws IOException { 16 noBufferedCopy();//不带缓冲 17 // bufferedCopy();//带缓冲 18 } 19 public static void noBufferedCopy()throws IOException{ 20 FileReader fr = new FileReader("E:\Test\1.txt"); 21 FileWriter fw = new FileWriter("E:\Test1.txt"); 22 char[] buf = new char[1024]; 23 int num = 0; 24 while ((num = fr.read(buf)) != -1) { 25 // 两种方式都可以 26 // fw.write(new String(buf,0,num)); 27 fw.write(buf, 0, num); 28 } 29 fr.close(); 30 fw.close(); 31 32 } 33 public static void bufferedCopy()throws IOException{ 34 // 缓冲包装 35 BufferedReader bufr=new BufferedReader(new FileReader("E:\Test\1.txt")); 36 BufferedWriter bufw=new BufferedWriter(new FileWriter("E:\Test1.txt")); 37 // 包装之后可以一行一行的读文本,且有缓冲效果,内部用数组封装,有效减少磁头的不停切换从而有保护存储介质的作用 38 String line=null; 39 while((line=bufr.readLine())!=null){ 40 bufw.write(line); 41 } 42 bufr.close(); 43 bufw.close(); 44 } 45 46 }
扩展:BufferedReader和BufferedWriter体现了一个java的设计模式=======装饰设计模式
原理:
设计模板:
2.文本复制指定编码
思路:
源:文本Reader=>FileReader × 不能指定编码=>父类InputStreamReader缓冲?BufferedReader
目的:文本Writer=>FileWriter × 不能指定编码=>父类OutputStreamWriter缓冲?BufferedWriter
1 /** *默认、指定GBK、指定UTF-8 */ public static void charSetCopy() throws IOException { // 源:文本Reader=>FileReader × 不能指定编码=>父类InputStreamReader // 目的:文本Writer=>FileWriter × 不能指定编码=>父类OutputStreamWriter InputStreamReader isr = new InputStreamReader(new FileInputStream( "E:\Test\1.txt"), "GBK"); OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream( "E:\11.txt")); OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream( "E:\12.txt"), "GBK"); OutputStreamWriter osw3 = new OutputStreamWriter(new FileOutputStream( "E:\13.txt"), "UTF-8"); BufferedReader bufr = new BufferedReader(isr); BufferedWriter bufw1 = new BufferedWriter(osw1); BufferedWriter bufw2 = new BufferedWriter(osw2); BufferedWriter bufw3 = new BufferedWriter(osw3); String line = null; while ((line = bufr.readLine()) != null) {//读 //写 bufw1.write(line); bufw1.newLine(); bufw1.flush(); bufw2.write(line); bufw2.newLine(); bufw2.flush(); bufw3.write(line); bufw3.newLine(); bufw3.flush(); } bufr.close(); bufw1.close(); bufw2.close(); bufw3.close(); }
3.图片及视频复制
思路:
源:InputStream,Reader?=>InputStream=>FileInputStream?BufferedInputStream
目的:OutputStream,Writer?=>OutputStream=>FileOutputStream?BufferedOutputStream
Demo:
1 package io; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 9 /** 10 * 将E盘1.avi复制到E盘2.avi 11 * 12 */ 13 public class CopyMedia { 14 15 public static void main(String[] args) throws IOException { 16 long start = System.currentTimeMillis(); 17 // copy(); 18 noBufferedCopy(); 19 long end = System.currentTimeMillis(); 20 System.out.println("time:" + (end - start) + "ms"); 21 } 22 23 public static void copy() throws IOException { 24 // 源:InputStream=>FileInputStream=>BUfferedInputStream 25 BufferedInputStream bufin = new BufferedInputStream( 26 new FileInputStream("E:\1.avi")); 27 // 目的:OutputStream=>FileOutputStream=>BufferedOutputStream 28 BufferedOutputStream bufout = new BufferedOutputStream( 29 new FileOutputStream("E:\2.avi")); 30 31 byte[] buf = new byte[8192]; 32 int len = 0; 33 34 // 读写 35 while ((len = bufin.read(buf)) != -1) { 36 bufout.write(buf, 0, len); 37 } 38 39 bufin.close(); 40 bufout.close(); 41 42 } 43 44 public static void noBufferedCopy() throws IOException { 45 FileInputStream fis = new FileInputStream("E:\1.avi"); 46 FileOutputStream fos = new FileOutputStream("E:\2.avi"); 47 48 byte[] buf = new byte[8192]; 49 int len; 50 51 while ((len = fis.read(buf)) != -1) { 52 fos.write(buf, 0, len); 53 } 54 55 fis.close(); 56 fos.close(); 57 } 58 59 }
4.键盘与控制台操作
以字节流的形式直接读键盘录入的数据到控制台
源:InputStream Reader?System.in是字节=>InputStream
目的:System.out=>OutputStream
以字符流形式将键盘录入的数据输出到控制台:
源:System.in=>InputStream(字节)?文本=>InputStreamReader?包装=>BufferedReader
目的:System.out=>OutputStream(字节)?文本=>OutputStreamWriter?包装=>BufferedWriter
将硬盘文本文件读到控制台
源:Reader=>FileReader=>BufferedReader
目的:System.Out=>OutputStream文本=>OutputStreamWriter=>BufferedWriter
将录入的数据以指定的编码存入到文件
源:System.in=>InputStream?文本=>InputStreamReader=>BufferedReader
目的:Writer=>FileWriter?编码=>OutputStreamWriter=>BufferedWriter
1 package io; 2 3 import java.io.*; 4 import java.util.*; 5 import java.text.*; 6 7 class KeyBoard 8 { 9 public static void main(String[] args)throws Exception 10 { 11 // readIn();//将键盘录入的数据输出到控制台 12 // readIn_2();//将硬盘文件读到控制台 13 // readIn_3();//以字节流的形式直接读键盘录入的数据到控制台 14 // readIn_4();//将录入的数据以指定的编码存入到文件 15 16 /********************************************* 17 特别说明:默认System.in对应源键盘,System.out对应控制台 18 通过System类的System.setIn(InputStream in)可以改变源, 19 如System.setIn(new FileInputStream("1.txt")); 20 通过System.setOut(PrintStream out)可以改变目的, 21 如System.setOut(new PrintStream("2.txt")); 22 23 所以:将需求1改为将键盘录入的数据保存到2.txt,只需要添加一句话 24 System.setOut(new PrintStream("2.txt")); 25 *********************************************/ 26 27 } 28 /* 需求1:将键盘录入的数据输出到控制台 29 30 源:InputStream Reader 31 文本?是!Reader 32 设备:键盘,System.in字节流 33 =>字节流转换成字符流InputStreamReader 34 InputStreamReader isr=new InputStreamReader(System.in); 35 需要缓冲吗?需要 36 BufferedReader bufr=new BufferedReader(isr); 37 38 目的:OutputStream Writer 39 文本?是的=>FileWriter 40 设备:控制台,System.out,字节流 41 =>需要将字节流转换成字符流=>OutputStreamWriter 42 OutputStreamWriter osw=new OutputStreamWriter(System.out); 43 需要缓冲吗?需要 44 BufferedWriter bufw=new BufferedWriter(osw); 45 46 47 48 */ 49 public static void readIn()throws IOException{ 50 // 源: 51 BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); 52 53 // 目的 54 BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out)); 55 56 String line=null; 57 while((line=bufr.readLine())!=null){ 58 if("over".equals(line)) 59 break; 60 bufw.write(line); 61 bufw.newLine(); 62 bufw.flush(); 63 } 64 bufr.close(); 65 bufw.close(); 66 } 67 /* 68 需求2:将文本读入控制台 69 源:Reader 70 设备:硬盘,文件,FileReader 71 缓冲:BufferedReader bufr=new BufferedReader(new FileReader("KeyBoard.java")); 72 73 目的:Writer 74 设备:控制台,System.out,字节流,需要转换 75 OutputStreamWriter osw=new OutputStreamWriter(System.out); 76 77 78 */ 79 80 public static void readIn_2()throws IOException{ 81 // 源: 82 BufferedReader bufr=new BufferedReader(new FileReader("KeyBoard.java")); 83 // 目的: 84 BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out)); 85 86 String line=null; 87 while((line=bufr.readLine())!=null){ 88 bufw.write(line); 89 bufw.newLine(); 90 bufw.flush(); 91 } 92 bufr.close(); 93 bufw.close(); 94 } 95 /* 96 需求3:直接以字节流的形式,输出键盘录入的内容 97 98 源:InputStream 99 设备:键盘,System.in 100 101 目的:OutputStream 102 设备:控制塔,System.out 103 */ 104 public static void readIn_3()throws IOException{ 105 InputStream in=System.in; 106 OutputStream out=System.out; 107 int len=0; 108 while((len=in.read())!=-1){ 109 out.write(len); 110 out.flush(); 111 } 112 in.close(); 113 out.close(); 114 } 115 116 /* 117 需求4:将录入的数据,以指定的编码格式存入到文件中 118 源:InputStream Reader 119 文本?Reader 120 设备:键盘,System.in,字节流=>转换 121 InputStreamReader isr=new InputStreamReader(System.in); 122 缓冲: 123 BufferedReader bufr=new BufferedReader(isr); 124 125 目的:OutputStream Writer 126 文本?Writer 127 设备:硬盘,文件,FileWriter 128 指定编码=>FileWriter做不到,找其父类=>OutputStreamWriter 129 构造方法:OutputStreamWriter(OutputSream out , String charsetName) 130 OutputStream+文件=>FileOutputStream 131 OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("F:\1.txt"),"UTF-8"); 132 需要缓冲技术吗? 133 BufferedWriter bufw=new BufferedWriter(osw); 134 */ 135 public static void readIn_4()throws IOException{ 136 // 源: 137 BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); 138 // 目的:(这里可以测试出默认,BGK,UTF-8的区别,UTF-8存放中文是字节更大) 139 BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("F:\1.txt"),"UTF-8")); 140 141 String line=null; 142 while((line=bufr.readLine())!=null){ 143 if("over".equals(line)) 144 break; 145 bufw.write(line); 146 bufw.newLine(); 147 bufw.flush(); 148 } 149 bufr.close(); 150 bufw.close(); 151 } 152 153 }
5.System类与PrintStream
需求:通过System.getProperties()获取虚拟机加载的信息,通过Map或PrintStream的list(PrintStream p)方法列出Key与Value,尝试将信息保留至文件。
1 package io; 2 3 import java.io.*; 4 import java.util.Map.Entry; 5 import java.util.Properties; 6 7 public class SystemDemo { 8 9 public static void main(String[] args)throws IOException { 10 // mapShow();//通过HashTable遍历 11 ioShow(); 12 } 13 public static void mapShow(){ 14 Properties pro=System.getProperties(); 15 for(Entry<Object,Object> e:pro.entrySet()){//增强for循环相当于写了Set集合的迭代器 16 String key=(String) e.getKey(); 17 String value=(String) e.getKey(); 18 19 System.out.println(key+"="+value); 20 } 21 } 22 23 public static void ioShow()throws IOException{ 24 System.setOut(new PrintStream("E:\1.txt"));//System类可以指定源和目的 25 Properties pro=System.getProperties(); 26 pro.list(System.out); 27 } 28 29 }
File类
流主要是对数据的处理,关于处理文件和文件系统,描述文本本身属性,要用File。
构造函数
public class FileDemo { public static void main(String[] args){ //构造函数File(String pathname) File f1 =new File("c:\abc\1.txt"); //File(String parent,String child) File f2 =new File("c:\abc","2.txt"); //File(File parent,String child) File f3 =new File("c:"+File.separator+"abc");//separator 跨平台分隔符 File f4 =new File(f3,"3.txt"); System.out.println(f1);//c:abc1.txt } }
创建方法
1.boolean createNewFile() 不存在返回true 存在返回false
2.boolean mkdir() 创建目录
3.boolean mkdirs() 创建多级目录
删除方法
1.boolean delete()
2.boolean deleteOnExit() 方法一可能删除失败,如删除的目标文件正在被使用;文件使用完成后删除
1 import java.io.File; 2 import java.io.IOException; 3 4 5 public class FileDemo2 { 6 public static void main(String[] args){ 7 File f =new File("d:\1.txt"); 8 try { 9 System.out.println(f.createNewFile());//当文件存在时返回false 10 System.out.println(f.delete());//当文件不存在时返回false 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 } 15 }
判断方法
1.boolean canExecute()判断文件是否可执行
2.boolean canRead()判断文件是否可读
3.boolean canWrite() 判断文件是否可写
4.boolean exists() 判断文件是否存在
5.boolean isDirectory()
6.boolean isFile()
7.boolean isHidden()
8.boolean isAbsolute()判断是否是绝对路径 文件不存在也能判断
获取方法
1.String getName()
2.String getPath()
3.String getAbsolutePath()
4.String getParent()//如果没有父目录返回null
5.long lastModified()//获取最后一次修改的时间
6.long length()
7.boolean renameTo(File f)
8.File[] liseRoots()//获取机器盘符
9.String[] list()
10.String[] list(FilenameFilter filter)
列出磁盘下的文件和文件夹:ListFiles()注意空指针异常:如E:System Volume Information
当读到系统文件时,可能会报空指针异常而停止程序,需要做一定的判断处理
1 public static void showAll_2(File f){ 2 //如果是文件,执行XX操作 3 if(f.isFile()){ 4 if(f.toString().endsWith(".rar")) 5 System.out.println(f); 6 } 7 //如果是文件夹,继续遍历 8 else if(f.isDirectory()){ 9 File[] files=f.listFiles(); 10 if(files==null) 11 System.out.println("这里是空的!!!!!!!-------------"+f.getAbsolutePath()); 12 //files不为空才遍历----论重要性!! 13 else if(files!=null) 14 for(File fChild:files) 15 showAll_2(fChild); 16 } 17 }
文件过滤
1.实现FilenameFilter接口;
2.实现boolean accept(File dir,String name); //dir表示文件的当前目录,name表示文件名;
1 import java.io.File; 2 import java.io.FilenameFilter; 3 public class FileDemo4 { 4 public static void main(String[] args){ 5 File[] files =File.listRoots(); 6 for(File file:files){ 7 System.out.println(file); 8 if(file.length()>0){ 9 String[] filenames =file.list(new FilenameFilter(){ 10 //file 过滤目录 name 文件名 11 public boolean accept(File file,String filename){ 12 return filename.endsWith(".mp3"); 13 } 14 }); 15 for(String filename:filenames){ 16 System.out.println(filename); 17 } 18 } 19 } 20 } 21 22 }