IO技术概述
- Output 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作
- Input 把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作
- 把上面的这种输入和输出动作称为IO操作
概念
- IO流用来处理设备之间的数据传输
- Java对数据的操作是通过流的方式
- Java用于操作流的类都在IO包中
- 流按流向分为两种:输入流,输出流。
- 流按操作类型分为两种:- 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
- 字符流 : 字符流只能操作纯字符数据,比较方便。
 
IO流常用父类
- 字节流的抽象父类:- InputStream
- OutputStream
 
- 字符流的抽象父类:- Reader
- Writer
 
IO程序书写
- 使用前,导入IO包中的类
- 使用时,进行IO异常处理
- 使用后,释放资源
编码表
- ascii: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx
- iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。
- GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数
- GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0
- GB18030:最新的中文码表,目前还没有正式使用。
- unicode:国际标准码表:无论是什么文字,都用两个字节存储。
- Java中的char类型用的就是这个码表。char c = 'a';占两个字节。
- Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。
- UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。
IO中的异常处理
如果不使用try catch 可以添加抛出声明
public static void main(String[] args) throws IOException{
}- 保证流对象变量,作用域足够
- catch里面,怎么处理异常- 输出异常的信息,目的看到哪里出现了问题
- 停下程序,从新尝试
 
- 如果流对象建立失败了,需要关闭资源吗- new 对象的时候,失败了,没有占用系统资源
- 释放资源的时候,对流对象判断null
- 变量不是null,对象建立成功,需要关闭资源
 
FileOutputStream fos = null;
// 注意变量的作用域问题
// try 外面声明变量,try 里面建立对象
try{
    fos = new FileOutputStream("s:\\a.txt");
    fos.write(100);
}catch(IOException ex){
    System.out.println(ex);
    throw new RuntimeException("文件写入失败,重试");
}finally{
    try{
        if(fos!=null)
          fos.close();
    }catch(IOException ex){
        throw new RuntimeException("关闭资源失败");
    }
}字节输出流FileOutputStream类
流对象的构造方法,可以创建文件,如果文件存在,直接覆盖
| Constructor and Description | 
|---|
| FileOutputStream(File file)
      创建文件输出流以写入由指定的 
      File对象表示的文件。 | 
| FileOutputStream(File file, boolean append)
      创建文件输出流以写入由指定的 
      File对象表示的文件。 | 
| FileOutputStream(FileDescriptor fdObj)
      创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。 
     | 
| FileOutputStream(String name)
      创建文件输出流以指定的名称写入文件。 
     | 
| FileOutputStream(String name, boolean append)
      创建文件输出流以指定的名称写入文件。 
     | 
- 创建流子类的对象,绑定数据目的
- 调用流对象的方法write写
- close释放资源
| Modifier and Type | Method and Description | 
|---|---|
| void | close()
      关闭此文件输出流并释放与此流相关联的任何系统资源。 
     | 
| protected void | finalize()
      清理与文件的连接,并确保当没有更多的引用此流时,将调用此文件输出流的 
      close方法。 | 
| FileChannel | getChannel() 
     返回与此文件输出流相关联的唯一的 FileChannel对象。 | 
| FileDescriptor | getFD()
      返回与此流相关联的文件描述符。 
     | 
| void | write(byte[] b)
      将 
      b.length个字节从指定的字节数组写入此文件输出流。 | 
| void | write(byte[] b, int off, int len)
      将 
      len字节从位于偏移量off的指定字节数组写入此文件输出流。 | 
| void | write(int b)
      将指定的字节写入此文件输出流。 
     | 
文件的续写和换行符号
/*
* 文件的续写
* FileOutputStream构造方法, 的第二个参数中,加入true
* 换行
* 在文件中,写入换行,符号换行\r\n 可以写在上一行的末尾, 也可以写在下一行的开头
*/
File file = new File("c:\\b.txt");
FileOutputStream fos = new FileOutputStream(file,true);
fos.write("hello\r\n".getBytes());
fos.write("world".getBytes());
fos.close();写入字节
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流对象的方法write写数据
//写1个字节
fos.write(97);
//关闭资源
fos.close();写入字节数组
FileOutputStream fos = new FileOutputStream("c:\\a.txt");
//流对象的方法write写数据
//写字节数组
byte[] bytes = {65,66,67,68};
fos.write(bytes);
//写字节数组的一部分,开始索引,写几个
fos.write(bytes, 1, 2);
//写入字节数组的简便方式
//写字符串
fos.write("hello".getBytes());
//关闭资源
fos.close();字节输入流FileInputStream类
流对象的构造方法
| Constructor and Description | 
|---|
| FileInputStream(File file)
      通过打开与实际文件的连接创建一个 
      FileInputStream,该文件由文件系统中的File对象file命名。 | 
| FileInputStream(FileDescriptor fdObj)
      创建 
      FileInputStream通过使用文件描述符fdObj,其表示在文件系统中的现有连接到一个实际的文件。 | 
| FileInputStream(String name)
      通过打开与实际文件的连接来创建一个 
      FileInputStream,该文件由文件系统中的路径名name命名。 | 
流对象的所有方法
| Modifier and Type | Method and Description | 
|---|---|
| int | available()
      返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。 
     | 
| void | close()
      关闭此文件输入流并释放与流相关联的任何系统资源。 
     | 
| protected void | finalize()
      确保当这个文件输入流的 
      close方法没有更多的引用时被调用。 | 
| FileChannel | getChannel() 
     返回与此文件输入流相关联的唯一的 FileChannel对象。 | 
| FileDescriptor | getFD()
      返回表示与此 
      FileInputStream正在使用的文件系统中实际文件的连接的FileDescriptor对象。 | 
| int | read()
      从该输入流读取一个字节的数据。 
     | 
| int | read(byte[] b)
      从该输入流读取最多 
      b.length个字节的数据为字节数组。 | 
| int | read(byte[] b, int off, int len)
      从该输入流读取最多 
      len字节的数据为字节数组。 | 
| long | skip(long n)
      跳过并从输入流中丢弃 
      n字节的数据。 | 
读取字节
FileInputStream fis = new FileInputStream("c:\\a.txt");
//读取一个字节,调用方法read 返回int
//使用循环方式,读取文件,  循环结束的条件  read()方法返回-1
int len = 0;//接受read方法的返回值
while( (len = fis.read()) != -1){
  System.out.print((char)len);
}
//关闭资源
fis.close();读取字节数组
/*
 *  FileInputStream读取文件
 *   读取方法  int read(byte[] b) 读取字节数组
 *   数组作用: 缓冲的作用, 提高效率
 *   read返回的int,表示读取到多少个有效的字节数
 */
/*
 * a.txt内容
 * abcdeded
 */
FileInputStream fis = new FileInputStream("c:\\a.txt");
// 创建字节数组
byte[] b = new byte[2];
int len = fis.read(b);
System.out.println(new String(b));// ab
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// cd
System.out.println(len);// 2
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// 1
len = fis.read(b);
System.out.println(new String(b));// ed
System.out.println(len);// -1
fis.close();对读取部分加上while循环并且把数组开到1024的长度增加读取效率,如果数组过大会占用更多的内存
FileInputStream fis = new FileInputStream("c:\\a.txt");
//创建字节数组
byte[] b = new byte[1024];
int len = 0 ;
while( (len = fis.read(b)) !=-1){
    System.out.print(new String(b,0,len));
}
fis.close();字节流复制文件读取单个字节
/*
 *  将数据源 c:\\a.txt
 *  复制到 d:\\a.txt  数据目的
 *  字节输入流,绑定数据源
 *  字节输出流,绑定数据目的
 *  
 *  输入,读取1个字节
 *  输出,写1个字节
 */
//定义两个流的对象变量
FileInputStream fis = null;
FileOutputStream fos = null;
try{
    //建立两个流的对象,绑定数据源和数据目的
    fis = new FileInputStream("c:\\t.zip");
    fos = new FileOutputStream("d:\\t.zip");
    //字节输入流,读取1个字节,输出流写1个字节
    int len = 0 ;
    while((len = fis.read())!=-1){
        fos.write(len);
    }
}catch(IOException ex){
    System.out.println(ex);
    throw new RuntimeException("文件复制失败");
}finally{
    try{
        if(fos!=null)
            fos.close();
    }catch(IOException ex){
        throw new RuntimeException("释放资源失败");
    }finally{
        try{
            if(fis!=null)
                fis.close();
        }catch(IOException ex){
            throw new RuntimeException("释放资源失败");
        }
    }
}字节流复制文件读取字节数组
/*
 *  字节流复制文件
 *   采用数组缓冲提高效率
 *   字节数组
 *   FileInputStream 读取字节数组
 *   FileOutputStream 写字节数组
 */
long s = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try{
    fis = new FileInputStream("c:\\t.zip");
    fos = new FileOutputStream("d:\\t.zip");
    //定义字节数组,缓冲
    byte[] bytes = new byte[1024*10];
    //读取数组,写入数组
    int len = 0 ; 
    while((len = fis.read(bytes))!=-1){
        fos.write(bytes, 0, len);
    }
}catch(IOException ex){
    System.out.println(ex);
    throw new RuntimeException("文件复制失败");
}finally{
    try{
        if(fos!=null)
            fos.close();
    }catch(IOException ex){
        throw new RuntimeException("释放资源失败");
    }finally{
        try{
            if(fis!=null)
                fis.close();
        }catch(IOException ex){
            throw new RuntimeException("释放资源失败");
        }
    }
}
long e = System.currentTimeMillis();
System.out.println(e-s);字符输出流FileWriter类
/*
 *   字符输出流
 *     java.io.Writer 所有字符输出流的超类
 *   写文件,写文本文件
 *   
 *   写的方法 write
 *     write(int c) 写1个字符
 *     write(char[] c)写字符数组
 *     write(char[] c,int,int)字符数组一部分,开始索引,写几个
 *     write(String s) 写入字符串
 *     
 *   Writer类的子类对象 FileWriter
 *   
 *   构造方法:  写入的数据目的
 *     File 类型对象
 *     String 文件名
 *     
 *   字符输出流写数据的时候,必须要运行一个功能,刷新功能
 *   flush()
 */
FileWriter fw = new FileWriter("c:\\1.txt");
//写1个字符
fw.write(100);
fw.flush();
//写1个字符数组
char[] c = {'a','b','c','d','e'};
fw.write(c);
fw.flush();
//写字符数组一部分
fw.write(c, 2, 2);
fw.flush();
//写如字符串
fw.write("hello");
fw.flush();
fw.close();字符输入流FileReader类
/*
 *  字符输入流读取文本文件,所有字符输入流的超类
 *    java.io.Reader
 *  专门读取文本文件
 *  
 *  读取的方法 : read()
 *   int read() 读取1个字符
 *   int read(char[] c) 读取字符数组
 *   
 *   Reader类是抽象类,找到子类对象 FileReader
 *   
 *   构造方法: 绑定数据源
 *     参数:
 *        File  类型对象
 *        String文件名
 */
FileReader fr = new FileReader("c:\\1.txt");
char[] ch = new char[1024];
int len = 0 ;
while((len = fr.read(ch))!=-1){
    System.out.print(new String(ch,0,len));
}
fr.close();flush方法和close方法区别
- flush()方法
- 用来刷新缓冲区的,刷新后可以再次写出,只有字符流才需要刷新
- close()方法
- 用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出
字符流复制文本文件
/*
 *  字符流复制文本文件,必须文本文件
 *  字符流查询本机默认的编码表,简体中文GBK
 *  FileReader读取数据源
 *  FileWriter写入到数据目的
 */
FileReader fr = null;
FileWriter fw = null;
try{
    fr = new FileReader("c:\\1.txt");
    fw = new FileWriter("d:\\1.txt");
    char[] cbuf = new char[1024];
    int len = 0 ;
    while(( len = fr.read(cbuf))!=-1){
        fw.write(cbuf, 0, len);
        fw.flush();
    }
}catch(IOException ex){
    System.out.println(ex);
    throw new RuntimeException("复制失败");
}finally{
    try{
        if(fw!=null)
            fw.close();
    }catch(IOException ex){
        throw new RuntimeException("释放资源失败");
    }finally{
        try{
            if(fr!=null)
                fr.close();
        }catch(IOException ex){
            throw new RuntimeException("释放资源失败");
        }
    }
} 
           最后一次更新于2019-07-17 13:54         
 
         Alipay
Alipay Wechat
Wechat 
            
            
   
  
0 条评论