Java IO最详解

刚开始学Java时候,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂。而且没有结合到java7 的最新技术,所以自己结合API来整理一下,有错的话请指正,也希望大家提出宝贵意见。

首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!)

Java I/O系统的类实在是太多了,这里我们只学习一些基本的和常用的,相信能够掌握这些就可以解决我们以后的普通应用了

 什么是数据流(字节流)                                                                                                                                                                      

数据流是指所有的数据通信通道;

有两类流,InputStream and OutputStream。

Java中每一种流的基本功能依赖于它们InputStream 用于read,OutputStream 用于write, 读和写都是相对与内存说的,读就是从其他地方把数据拿进内存,写就是把数据从内存推出去
这两个都是抽象类,不能直接使用

InputStream 的方法有:                                                                                                                             

1.read() :从流中读入数据 有3中方式:
2.int read(): 一次读一个字节
3.int read(byte[]) :读多个字节到数组中
4.int read(byte[],int off,int len) :指定从数组的哪里开始,读多长
5.skip() :跳过流中若干字节
6.available() :返回流中可用字节数,但基于网络时无效,返回0
7.markSupported(): 判断是否支持标记与复位操作
8.mark() :在流中标记一个位置,要与markSupported()连用
9.reset() :返回标记过的位置
10.close() :关闭流

OutputStream 的方法:                                                                                                                               

1.write(int) :写一个字节到流中
2.write(byte[]): 将数组中的内容写到流中
3.write(byte[],int off,int len): 将数组中从off指定的位置开始len长度的数据写到流中
4.close() :关闭流
5.flush() :将缓冲区中的数据强制输出

File 类                                                                                                                                                      

File 可以表示文件也可以表示目录,File 类控制所有硬盘操作
构造器:
1.File(File parent,String child): 用父类和文件名构造
2.File(String pathname) :用绝对路径构造
3.File(String parent,String child): 用父目录和文件名构造
4.File(URI uri) :用远程文件构造
常用方法:

-----------------------------------------------------------------------------------------------------------------------------------------------------------

1.boolean createNewFile();

2.boolean exists();

例子:
//建立 test.txt 文件对象,判断是否存在,不存在就创建
import java.io.*;

public class CreateNewFile{
    public static void main(String args[]){
      File f=new File("test.txt");
      try{
         if(!f.exists())
            f.createNewFile();
         else
           System.out.println("exists");
        }catch(Exception e){
         e.printStackTrace();
        }
    }
}

---------------------------------------------------------------------------------------------------------------------------------------------------------

3.boolean mkdir()/mkdirs()

4.boolean renameTo(File destination)
例子://看一下这 mkdir()/mkdirs() 的区别和 renameTo 的用法
import java.io.*;
public class CreateDir{
    public static void main(String args[]){
       File f=new File("test.txt");
       File f1=new File("Dir");
       File f2=new File("Top/Bottom");
       File f3=new File("newTest.txt");
       try{
         f.renameTo(f3);
          f1.mkdir();
          f2.mkdirs();
       }catch(Exception e){
         e.printStackTrace();
       }
    }
}

--------------------------------------------------------------------------------------------------------------------------------------------------------------

String getPath()/getAbsolutePath()

String getParent()/getName()

例子://硬盘上并没有parent 目录和 test.txt 文件,但我们仍然可以操作,因为我们创建了他们的对象,是对对象进行操

import java.io.*;
public class Test{
    public static void main(String args[]){
        File f=new File("parent/test.txt");
        File f1=new File("newTest.txt");
        try{
           System.out.println(f.getParent());
           System.out.println(f.getName());
           System.out.println(f1.getPath());
           System.out.println(f1.getAbsolutePath());
          }catch(Exception e){
             e.printStackTrace();
          }
      }
}
----------------------------------------------------------------------------------------------------------------------------------------------------------

String list[] //显示目录下所有文件
long lastModified() //返回 1970.1.1 到最后修改时间的秒数
boolean isDirectory()
例子://列出目录下的所有文件和目录,最后修改时间,是目录的后面标出<DIR>,是文件的后面标出文件长度

import java.io.*;
import java.util.*;
public class Dir{
     public static void main(String args[]){
          File f=new File("Dir");
          String[] listAll=null;
          File temp=null;
          try{
              listAll=f.list();
              for(int i=0;i<listAll.length;i++){
                   temp=new File(listAll<i>);
                   System.out.print(listAll<i>+"\t");
                   if(temp.isDirectory())
                         System.out.print("\t<DIR>\t");
                   else
                     System.out.print(temp.length()+"\t");
                     System.out.println(new Date(temp.lastModified()))
           }
         }catch(Exception e){
             e.printStackTrace();
        }
    }
}
文件流的建立                                                                                                                                                                               
File f=new File("temp.txt");
FileInputStream in=new FileInputStream(f);
FileOutputStream out=new FileOutputStream(f);
例子:文件拷贝
import java.io.*;
public class Copy{
public static void main(String args[]){
     FileInputStream fis=null;
     FileOutputStream fos=null;
     try{
        fis=new FileInputStream("c2.gif");
        fos=new FileOutputStream("c2_copy.gif");
        int c;
        while((c=fis.read()) != -1)
            fos.write(c);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(fis != null) try{ fis.close(); }catch(Exception e){ e.printStackTrace(); }
            if(fos!= null) try{ fos.close(); }catch(Exception e){ e.printStackTrace(); }
        }
    }
}

<span style="background-color: rgb(0, 102, 0);"><span style="color:#FFFFFF;"><strong>
</strong></span></span>
缓冲区流                                                                                                                                                                                             
BufferedInputStream
BufferedOutputStream
他们是在普通文件流上加了缓冲的功能,所以构造他们时要先构造普通流
例子:文件拷贝的缓冲改进
import java.io.*;
public class Copy{
   public static void main(String args[]){
         BufferedInputStream bis=null;
         BufferedOutputStream bos=null;
         byte buf[]=new byte[100];
         try{
             bis=new BufferedInputStream(new FileInputStream("persia.mp3"));
             bos=new BufferedOutputStream(new FileOutputStream("persia_copy.mp3"));
             int len=0;
             while( true ){
                   len=bis.read(buf);
                   if(len<=0) break;
                   bos.write(buf,0,len);
             }
             bos.flush();//缓冲区只有满时才会将数据输出到输出流,用flush()将未满的缓冲区中数据强制输出
          }catch(Exception e){
             e.printStackTrace();
          }finally{
             if(bis != null) try{ bis.close(); }catch(Exception e){ e.printStackTrace(); }
             if(bos!= null) try{ bos.close(); }catch(Exception e){ e.printStackTrace(); }
         }
    }
}

原始数据流                                                                                                                                        

DataInputStream
DataOutputStream
他们是在普通流上加了读写原始型数据的功能,所以构造他们时要先构造普通流
方法:
readBoolean()/writeBoolean()
readByte()/writeByte()
readChar()/writeByte()
......
例子://这个流比较简单,要注意的就是读时的顺序要和写时的一样

import java.io.*;
public class DataOut{
     public static void main(String args[]){
     DataOutputStream dos=null;
     try{
         dos=new DataOutputStream(new FileOutputStream("dataout.txt"));
         dos.writeInt(1);
         dos.writeBoolean(true);
         dos.writeLong(100L);
         dos.writeChar('a');
      }catch(Exception e){
         e.printStackTrace();
      }finally{
         if(dos!=null)
         try{
            dos.close();
         }catch(Exception e){
      }
    }
  }
}
import java.io.*;
public class DataIn{
     public static void main(String args[]){
     DataInputStream dis=null;
     try{
        dis=new DataInputStream(new FileInputStream("dataout.txt"));
        System.out.println(dis.readInt());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readLong());
        System.out.println(dis.readChar());
      }catch(Exception e){
        e.printStackTrace();
      }finally{
         if(dis!=null)
        try{
           dis.close();
        }catch(Exception e){
      }
    }
  }
}
对象流                                                                                                                                                                                             

串行化:对象通过写出描述自己状态的数值来记述自己的过程叫串行话
对象流:能够输入输出对象的流
将串行化的对象通过对象流写入文件或传送到其他地方
对象流是在普通流上加了传输对象的功能,所以构造对象流时要先构造普通文件流
注意:只有实现了Serializable接口的类才能被串行化
例子:

import java.io.*;
class Student implements Serializable{
    private String name;
    private int age;

    public Student(String name,int age){
         this.name=name;
         this.age=age;
     }

     public void greeting(){
          System.out.println("hello ,my name is "+name);
     }

     public String toString(){
          return "Student["+name+","+age+"]";
   }
}

public class ObjectOutTest{
      public static void main(String args[]){
      ObjectOutputStream oos=null;
      try{
         oos=new ObjectOutputStream(new FileOutputStream("student.txt"));
         Student s1=new Student("Jerry",24);
         Student s2=new Student("Andy",33);

         oos.writeObject(s1);
         oos.writeObject(s2);
        }catch(Exception e){
             e.printStackTrace();
        }finally{
             if(oos!=null)
             try{
                oos.close();
              }catch(Exception e){
                   e.printStackTrace();
             }
          }
     }
}
import java.io.*;
public class ObjectInTest{
       public static void main(String args[]){
       ObjectInputStream ois=null;
       Student s=null;
       try{
         ois=new ObjectInputStream(
         new FileInputStream("student.txt"));
         System.out.println("--------------------");
         s=(Student)ois.readObject();
         System.out.println(s);
         s.greeting();
         System.out.println("--------------------");
         s=(Student)ois.readObject();
         System.out.println(s);
         s.greeting();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(ois!=null)
            try{
              ois.close();
            }catch(Exception e){
             e.printStackTrace();
          }
       }
    }
}
字符流 InputStreamReader/OutputStreamWriter                                                                                                                                  
上面的几种流的单位是 byte,所以叫做字节流,写入文件的都是二进制字节,我们无法直接看,下面要学习的是字节流
Java采用 Unicode 字符集,每个字符和汉字都采用2个字节进行编码,ASCII 码是 Unicode 编码的自集
InputStreamReader 是 字节流 到 字符桥的桥梁 ( byte->char 读取字节然后用特定字符集编码成字符)
OutputStreamWriter是 字符流 到 字节流的桥梁 ( char->byte )
他们是在字节流的基础上加了桥梁作用,所以构造他们时要先构造普通文件流
我们常用的是:
BufferedReader 方法:readLine()
PrintWriter 方法:println()

例子:
import java.io.*;
public class PrintWriterTest{
     public static void main(String args[]){
     PrintWriter pw=null;
     try{
        pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream("bufferedwriter.txt")));
        pw.println("hello world");
      }catch(Exception e){
        e.printStackTrace();
      }finally{
        if(pw!=null)
             try{
                pw.close();
               }catch(Exception e){
                  e.printStackTrace();
           }
       }
   }
}
import java.io.*;
public class BufferedReaderTest{
         public static void main(String args[]){
         BufferedReader br=null;
        try{
           br=new BufferedReader(new InputStreamReader(new FileInputStream("bufferedwriter.txt")));
           System.out.println(br.readLine());
          }catch(Exception e){
              e.printStackTrace();
         }finally{
           if(br!=null)
             try{
                br.close();
             }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
随机存取文件 RandomAccessFile                                                                                                                                                       
可同时完成读写操作
支持随机文件操作的方法:
readXXX()/writeXXX()
seek() 将指针调到所需位置
getFilePointer() 返回指针当前位置
length() 返回文件长度
例子:把若干个32位的整数写到一个名为 “temp.txt”的文件中,然后利用seek方法,以相反的顺序再读取这些数据
import java.io.*;
public class RandomFile{
   public static void main(String args[]){
        RandomAccessFile raf=null;
        int data[]={12,31,56,23,27,1,43,65,4,99};
        try{
           raf=new RandomAccessFile("temp.txt","rw");
           for(int i=0;i<data.length;i++)
                raf.writeInt(data<i>);
                for(int i=data.length-1;i>=0;i--){
                     raf.seek(i*4);
                     System.out.println(raf.readInt());
                }
           }catch(Exception e){
               e.getMessage();
           }finally{
               if(raf!=null)
               try{
                  raf.close();
              }catch(Exception e){
                 e.getMessage();
            }
       }
   }
} 
小结                                                                                                                                                                                                  

这部分的难点就是类比较复杂,尤其是每个类的构造方式,我认为记住下面这个图比记类的继承关系更好些

字节流:

InputStream
|-- FileInputStream (基本文件流)
|-- BufferedInputStream
|-- DataInputStream
|-- ObjectInputStream
OutputStream 同上图
BufferedInputStream DataInputStream ObjectInputStream 只是在 FileInputStream 上增添了相应的功能,构造时先构造FileInputStream

 字符流:
Reader
|-- InputStreamReader (byte->char 桥梁)
|-- BufferedReader (常用)

Writer
|-- OutputStreamWriter (char->byte 桥梁)
|-- BufferedWriter
|-- PrintWriter (常用)

 随机存取文件 RandomAccessFile






  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未名胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值