IO流顾名思义Input&Output,IO体系的建立依据四个基类:
①InputStream在认识这个体系之前有两个非常重要的类需要说一下:File类(文件的创建和删除以及文件属性的显示)和RandomAccessFile类(功能最全的流,可以完成输入和输出)
File类:
/** * java中对于文件的定义分为:文件和目录 * @throws IOException */ @Test public void testFile() throws IOException{ System.out.println("请输入您要操作的盘符:"); Scanner scanner = new Scanner(System.in); //读取盘符 String disk=scanner.nextLine(); File file=new File(disk); //访问文件名 File[] listTable = file.listFiles(); // listTable[10].renameTo(new File("hello111.txt")); for(int i=0;i<listTable.length;i++){ // System.out.println(i+1+" "+listTable[i].getCanonicalPath()); // System.out.println(i+1+" "+listTable[i].getParent()); // System.out.println(i+1+" "+listTable[i].getPath()); // System.out.println(i+1+" "+listTable[i].getAbsolutePath()); // System.out.println(i+1+" "+listTable[i].getName()); } //文件检测 System.out.println(listTable[10].isFile());//是否为一个真正的文件 System.out.println(listTable[10].isDirectory());//是否为一个文件目录 System.out.println(listTable[10].isHidden());//是否被隐藏 System.out.println(listTable[10].isAbsolute());// System.out.println(listTable[10].canExecute());//可执行? System.out.println(listTable[10].canRead());//可读? System.out.println(listTable[10].canWrite());//可写? //常规信息 System.out.println(new Date(listTable[10].lastModified())); System.out.println(listTable[10].length()); //文件操作 File test=new File("E:/helloworld!!!"); test.createNewFile(); // 在指定目录下创建文件 File.createTempFile("123", ".java", listTable[10]); //删除文件 test.delete(); //目录操作 test.mkdir(); }
/** * 从多行文本的指定位置插入字符串,不是覆盖 * RandomAccessFile既可充当输入流又可充当输出流,只要在构造器重设置下mode即可 * "r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 "rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。 "rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 "rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。 */ @Test public void testRandomAccessFile(){ RandomAccessFile in = null; try { in = new RandomAccessFile(new File("hello.txt"), "rw"); /** * 移动指针位置 */ in.seek(4); int len=0; byte[] content=new byte[1024]; //先将当前位置之后的字符全部保存 StringBuffer sb=new StringBuffer(); while((len=in.read(content))!=-1){ sb.append(new String(content,0,len)); } //重新找回原先的位置,进行覆盖 in.seek(4); in.write("Mr凡先生好帅!!!".getBytes()); in.write(sb.toString().getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }
大致的轮廓就清晰了!
// 注意点: // 1.FileInputStream的pathName一定要存在,否则会报FileNotfound异常 // 2.read():首先指针在文件内容前一个,当调用这个方法的时候文件指针会先向后移一个字节 // 然后读出这个字节的值,但是此时带来了一个问题:①中文怎么办???②为什么循环需要有b=fis.read()(就是图中写法二的问题在哪儿 )??? // 3.read(byte[] b)提升了效率,并且解决了中文输出的问题,对于问题②在这里也是作为字符串的一种截取。但是read()不需要截取啊!!! // 所以问题②还没有实质性的解决 @Test public void testFileInputStream() { // 定义变量方便在try catch 和finally块中使用 FileInputStream fis = null; try { /* ======================read()========================= */ // int b; // while((b=fis.read())!=-1){ // System.out.print((char)b); // } /** * 写法二:无法进行读取为什么? */ // while(fis.read()!=-1){ // System.out.print((char)fis.read()); // } /* ======================read()========================= */ /* ===================read(byte[] b)==================== */ /* * fis = new FileInputStream("F:\\helloWorld.txt"); //读取文件了内容 byte[] * content=new byte[1024]; fis.read(content); System.out.println(new * String(content)); */ fis = new FileInputStream("F:\\helloWorld.txt"); // 读取文件了内容 byte[] content = new byte[5]; int len = 0; while ((len = fis.read(content)) != -1) { // 错误写法① /* * for(byte b:content){ System.out.print((char)b); } */ // 错误写法② /* * for(int i=0;i<content.length;i++){ * System.out.print((char)content[i]); } */ // 错误写法③ // System.out.print(new String(content)); // 错误原因分析:由前面代码可知,缓冲区为5,文件内容为123456789,那么当文件第二次读取时 // 只有前四位被覆盖了,而最后一位没有被覆盖,所以如果讲第二次的数组全部答应出来是肯定会出现问题的:1234567895 // 方法一 // System.out.print(new String(content,0,len)); // 方法二 for (int i = 0; i < len; i++) { System.out.print((char) content[i]); } } /* ===================read(byte[] b)==================== */ } catch (Exception e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 注意点: FileOutputStream(String * pathName)中的文件不存在时,会自动创建,若无法正常创建时会报出FileNotfound异常 * 如果pathName是一个文件,或者是一个已经存在但是无法正常打开那么也会FileNotfound异常 * 如果文件已存在并且能够被正常打开,那么当往文件里面写东西的时候会将原本的内容完全覆盖 * 。如果想让文件不被覆盖,需要使用RandomAccessFile类 */ @Test public void testFileOutputStream() { FileOutputStream fos = null; try { fos = new FileOutputStream("F:/"); int len = 0; byte[] content = "我是李刚我怕谁!".getBytes(); fos.write(content); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * 将文件从一个文件复制到另一个文件夹下 * 通过FileInputStream将文件内容读入并通过FileOutputStream将读取的内容输入指定的文件 */ @Test public void testCopy() { String src = "F:\\helloWorld.txt"; String des = ""; } public void copyFile(String src, String des) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(src); fos = new FileOutputStream(des); byte[] content = new byte[1024]; int len = 0; while ((len = fis.read(content)) != -1) { fos.write(content, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * * 复制文本文件 */ @Test public void copyByChar() { FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("F:\\helloWorld.txt"); fw = new FileWriter("test.txt"); char[] content = new char[1024]; int len = 0; while ((len = fr.read(content)) != -1) { fw.write(content, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * 通过处理流(缓冲流)进行非文本文件的复制 * 缓冲流需要注意的点:1.作用可以提升效率,原因是由于底层采用的是非阻塞的数组 * 2.缓冲流关闭时候可以关闭对应的节点流 * 3.需要使用flush清空缓冲输出流中的数据 */ public void copyByBuffer(String src, String des) { //定义缓冲流 BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //包装缓冲流 FileInputStream fis = new FileInputStream(src); FileOutputStream fos = new FileOutputStream(des); bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); int len = 0; byte[] content = new byte[1024]; while ((len=bis.read(content)) != -1) { bos.write(content, 0, len); bos.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(bos!=null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if(bis!=null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** *BufferedReader的readLine()和BufferedWriter的newLine()=="\n"=="\r\n" */ @Test public void testReadLine(){ BufferedReader br=null; BufferedWriter bw=null; try { FileReader fr=new FileReader("hello.txt"); FileWriter fw=new FileWriter("common.txt"); br = new BufferedReader(fr); bw = new BufferedWriter(fw); String line=null; while((line=br.readLine())!=null){ //方法一 bw.write(line+"\n"); bw.flush(); //方法二 /* bw.write(line); bw.newLine(); bw.flush(); */ } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if(br!=null){ try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * 影响效率的两个因素:①是否使用了缓冲流②读取的数组大小是否合适 */ @Test public void testEfficient(){ String src="C:\\Users\\Administrator\\Desktop\\1.wmv"; String des1="C:\\Users\\Administrator\\Desktop\\2.wmv"; String des2="C:\\Users\\Administrator\\Desktop\\3.wmv"; long startTime=System.currentTimeMillis(); copyFile(src, des1); long endTime=System.currentTimeMillis(); System.out.println("未使用缓冲流之前:"+(endTime-startTime)); long startTime1=System.currentTimeMillis(); copyByBuffer(src, des2); long endTime1=System.currentTimeMillis(); System.out.println("未使用缓冲流之前:"+(endTime1-startTime1)); }
/** * 考虑到对于纯文本文件的读取时字符流的效率往往比字节流的效率高很多,所以当文本以字节流 * 形式读入的时候为了提升效率java设计了一种处理流(转换流),将字节流转化为字符流,从而 * 提升了文本文件的读取速度。 * 转换流读取文件的过程: * 读:FileIutputStream->IutputStreamReader->FileReader * 解码:字节数组——》字符串 * 写:FileOnputStream->OuputStreamWriter->FileWriter * 编码:字符串-》字节数组 * * * 通过这个例子我们可以发现处理流编程的一个特点,就是将输入和输出流不停得向着顶端封装然后直接在顶端操作就好了!!! */ @Test public void testStream2RW(){ BufferedReader br=null; BufferedWriter bw=null; try { File file1=new File("hello.txt"); File file2=new File("hello2.txt"); //解码 FileInputStream fis=new FileInputStream(file1); InputStreamReader isr=new InputStreamReader(fis); br = new BufferedReader(isr); //编码 FileOutputStream fos=new FileOutputStream(file2); OutputStreamWriter osw=new OutputStreamWriter(fos); bw = new BufferedWriter(osw); String content=null; while((content=br.readLine())!=null){ bw.write(content); bw.newLine(); bw.flush(); } } catch (IOException e) { e.printStackTrace(); }finally{ if(br!=null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block } } if(br!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //从控制台接受输入 @Test public void testStandard(){ BufferedInputStream bis=null; try { InputStream is=System.in; InputStreamReader isr=new InputStreamReader(is); BufferedReader br=new BufferedReader(isr); String content=null; while(true){ System.out.println("请输入一个字符串:"); content=br.readLine(); if("e".equalsIgnoreCase(content)||"exit".equalsIgnoreCase(content)){ System.out.println("已退出"); break; } System.out.println(content.toUpperCase()); /* InputStream is=System.in; bis = new BufferedInputStream(is); byte[] content=new byte[1024]; while(true){ System.out.println("请输入一个字符串:"); bis.read(content); String inputStr=new String(content); if("e\r\n".equalsIgnoreCase(inputStr)||"exit\r\n".equalsIgnoreCase(inputStr)){ System.out.println("已退出"); break; } System.out.println(inputStr.toUpperCase()); */ } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bis!=null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * 重定向从在控制台显示到文件中显示,PrintStream PrintWriter */ @Test public void testPrint(){ //接受控制台输入的字符串 BufferedReader br =null; PrintStream ps=null; try { br = new BufferedReader(new InputStreamReader(System.in)); ps = new PrintStream(new FileOutputStream(new File("hello.txt"))); String content = null; while((content=br.readLine())!=null){ System.out.println("请输入需要录入的数据"); if("e".equalsIgnoreCase(content)||"exit".equalsIgnoreCase(content)){ System.out.println("文件内容录入完毕,请查看hello.txt!"); } ps.println(content); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if(ps!=null){ ps.close(); } if(br!=null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
package com.heima; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.junit.Test; public class TestSerializable { /** * 序列化:将对象特征提取成一组二进制流 * 反序列话:通过二进制流解析出对象 */ @Test public void testOutputStream(){ ObjectOutputStream ois = null; try { ois = new ObjectOutputStream(new FileOutputStream(new File("person.txt"))); Person person=new Person("tang", 12); ois.writeObject(person); ois.flush(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testObjectInputStream(){ ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream(new File("person.txt"))); Person person=new Person("tang", 12); System.out.println(ois.readObject().toString()); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /** * 序列化要求: * 1.实体类必须继承Serializable接口 * 2.所有的数据成员类型必须实现Serializable接口 * 3.static和transient不能序列化 * @author John */ class Person implements Serializable{ private static final long serialVersionUID = 4848325561922145707L; private String name; private int age; public String getName() { return name; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
package com.heima; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.junit.Test; public class TestSerializable { /** * 序列化:将对象特征提取成一组二进制流 * 反序列话:通过二进制流解析出对象 */ @Test public void testOutputStream(){ ObjectOutputStream ois = null; try { ois = new ObjectOutputStream(new FileOutputStream(new File("person.txt"))); Person person=new Person("tang", 12); ois.writeObject(person); ois.flush(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testObjectInputStream(){ ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream(new File("person.txt"))); Person person=new Person("tang", 12); System.out.println(ois.readObject().toString()); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /** * 序列化要求: * 1.实体类必须继承Serializable接口 * 2.所有的数据成员类型必须实现Serializable接口 * 3.static和transient不能序列化 * @author John */ class Person implements Serializable{ private static final long serialVersionUID = 4848325561922145707L; private String name; private int age; public String getName() { return name; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }