黑马程序员--IO

来源:互联网 发布:什么情况下使用网络猫 编辑:程序博客网 时间:2024/06/14 09:33

-------Android培训、Java培训、期待与您交流! ----------

I/O流概述:

为进行数据的输入/输出操作,Java中把不同的输入/输出源(键盘、文件、网络连接等)抽象表述为“流”(stream)。
Stream是从起源(source)到接收(sink)的有序数据
java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能。
按照流的方向分两种基本的流:输入流和输出流
输入流 :只能从中读取字节数据,而不能向其写出数据
输出流 :只能向其写入字节数据,而不能从中读取数据
按照流所处理的数据类型划分,可以分为:
字节流:用于处理字节数据(8个bit)
  包括InputStream/OutputStream。
字符流:用于处理Unicode字符数据(16个bit)。
  包括Writer/Reader

节点流和处理流:

按照流的角色划分,分为节点流和处理流
可以从/向一个特定的IO设备(如磁盘、网络)读/写数据的流,称为节点流。节点流也被称为低级流。例如:InputStream和Reader的子类都有read()的方法,OutputStream和Writer的子类都有write()的方法,用于读取/写入一个字节或字节数组.但是在实际使用中很少使用单一流类产生的输入/输出流.而是使用这两个方法给其他的流类提供数据

实现对一个已存在的流的连接和封装,通过所封装的流的功能调用
实现数据读/写功能的流,称为处理流。处理流也被称为高级流

InputStream/OutputStream

InputStream/OutputStream用于处理字节数据。它们读/写流的方式都是以字节为单位进行的。

InputStream基本方法:

三个基本的read方法:
int read():读取一个字节,并将它返回。
int read(byte[] buffer):将数据读入一个字节数组,同时返回读取的字节数。
int read(byte[] buffer, int offset, int length):将数据读入一个字节数组,放到数组的offset指定的位置开始,并用length来指定读取的最大字节数。
注意:以上三个方法在读取到文件末尾时,都返回-1.可以用来判断是否全部读取文件
其它方法:
void close():关闭流。
int available():返回可以从中读取的字节数。
long skip(long n):在输入流中跳过n个字节,将实际跳过的字节数返回。
boolean markSupported():判断流是否支持标记功能。
void mark(int readlimit):在支持标记的输入流的当前位置设置一个标记。
void reset():返回到流的上一个标记。注意必须流支持标记功能。

常见InputStream类:

低级InputStream类(节点流):
InputStream:所有字节流的超类,定义了很多用于处理输入流的方法,是个抽象类
ByteArrayInputStream:为读取字节数组设计的流,用于从文件中读取二进制数据
PipedInputStream:管道流,
FileInputStream:用于读取文件中的信息
FilterInputStream:继承自InputStream,能将一个流连接到另一个流的末端,将两个流连接起来
高级InputStream类(处理流):
DataInputStream:可以从低级流中读取简单数据和String类型的数据.这样,可以将底层的读取细节隐藏起来,而直接处理简单类型和String类型的数据
BufferedInputStream:提供缓冲能力的字节输入流


InputStream例子:

byte[] buff = new byte[1024];    int n;    FileInputStream fis = null;     try{        fis = new FileInputStream(“C:\\a.txt”);      while((n = fis.read(buff))!=-1){                            System.out.write(buff, 0, n);             }     }    catch (FileNotFoundException e){        System.out.println("没有找到文件");        System.exit(1);     }


OutputStream基本方法:

三个基本的write方法:
void write(int c)
void write(byte[] buffer)
void write(byte[] buffer, int offset, int length)
  其它方法
void close()
void flush():将缓冲中的字节发送到流中,同时清空缓冲区

OutputStream类:

低级OutputStream,用来向设备中写入字节流
OutputStream:所有字节输出流的基类
ByteArrayOutputStream :按字节数组方式向设备中写入字节流的类
PipedOutputStream:管道输出流
高级OutputStream
DataOutputStream:可以向低级流中写入简单数据和String类型的数据.这样,可以将底层的写入细节隐藏起来,而直接处理简单类型和String类型的数据
BufferedOutputStream:提供缓冲能力的字节输出流


FileOutputStream out; //声明一个Print Stream流PrintStream p; try {out = new FileOutputStream("myfile.txt");p = new PrintStream( out );p.println ("面朝大海,春暖花开");p.close();} catch (Exception e) {System.err.println ("Error writing to file");}

 

通过Stream拷贝文本文件例子;

通过FileInputStream和FileOutputStream,实现从一个文本文件拷贝内容到另一个文件的例子
通过FileInputStream从源文本文件中读出数据,然后通过FileOutputStream写入到另外一个文本文件中。
使用高级流(BufferedInputStream/BufferedOutputStream)
   对低级流进行包装

import java.io.*;public class CopyFile{public boolean copyFile(String src,String des){    File srcFile,desFile;    srcFile = new File(src);    desFile = new File(des);    FileInputStream fis = null;    FileOutputStream fos = null;    try{      desFile.createNewFile();      fis = new FileInputStream(srcFile);      fos = new FileOutputStream(desFile);      int bytesRead;      byte[] buf = new byte[4 * 1024];  // 4K buffer      while((bytesRead=fis.read(buf))!=-1){        fos.write(buf,0,bytesRead);      }      fos.flush();      fos.close();      fis.close();    }catch(IOException e){      System.out.println(e);      return false;    }      return true;} public static void main(String args[]){CopyFile cf = new CopyFile();String src = args[0];String des = args[1];if(cf.copyFile(src,des)){System.out.println("拷贝成功!");}else{System.out.println("拷贝失败!");}}}

 

Reader/Writer:

Reader/Writer处理的是字符类型的数据。它处理流的方式是以字符为单位进行的。
Reader/Writer和InputStream/OutputStream一样,也分为节点流(低级流)和处理流(高级流)。
Reader和InputStream一样,用于从流中读取数据。它和InputStream的区别在于,InputStream以字节为单位操作流,而Reader以字符为单位操作流

Reader常用方法:

读取方法:
int read():用于从流中读出一个字符,并将它返回。
int read(char[] buffer):将从流中读出的字符放到字符数组buffer中,返回读出的字符数。
int read(char[] buffer,int offset,int length):将读出的字符放到字符数组的指定offset开始的空间,每次最多读出length个字符。
其他方法:
void close():关闭Reader流。
boolean ready():判断流是否已经准备好被读取。
skip(long n):跳过指定的n个字符。
boolean markSupported():和InputStream中的markSupported方法类似。
void mark(int readAheadLimit):和InputStream中的mark方法类似。
void reset():和InputStream中的reset方法类似。

Reader相关类:

低级Reader类:
CharArrayReader:
StringReader
PipedReader
FileReader
高级Reader类
BufferedReader
InputStreamReader
LineNumberReader

Reader类层次:

import java.io.*;public class FileReaderDemo {public static void main (String[] args) {FileReaderDemo t = new FileReaderDemo();t.readMyFile();}void readMyFile() {String record = null;int recCount = 0;try {FileReader fr = new FileReader("C:/nos/tmp/mydata.txt");BufferedReader br = new BufferedReader(fr);record = new String();while ((record = br.readLine()) != null) {recCount++;System.out.println("Line" + recCount + ": " + record);}br.close();fr.close();} catch (IOException e) {e.printStackTrace();}}}

 

InputStreamReader:

InputStreamReader能将字节流转换为一个Reader,即能将字节流转换为字符流
        public static void readRile() {
  try {
                  InputStreamReader isr = new InputStreamReader(new
                                                               FileInputStream("c:\\a.txt"));
   BufferedReader bufferedReader = new BufferedReader(isr)   String str = "";
   while ((str =bufferedReader.readLine() ) != null){
    System.out.println(str);
   }
  } catch (FileNotFoundException e) {   
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

CharArrayReader:

从内存的字符串数组中读取字符,它的数据源是一个字符数组,它把字符数组类型转换为Reader类型:

      public static void readRile() {  char [] arrays = {'a','你','好','啊','t'};  CharArrayReader reader = new CharArrayReader(arrays);  int i = 0;  try {   while ( (i = reader.read()) != -1){    System.out.print((char)i);   }  } catch (IOException e) {   // TODO 自动生成 catch 块   e.printStackTrace();  }              reader.close(); }


StringReader:

把String类型转换为Reader类型:

public static void readRile() {String str = “经费来的快速家法律监督是分机离开收到\n将发了开                                  赛发了看见的说\n发觉脸上开发介绍两分巨大胜利\n";StringReader reader = new StringReader(str);int i = 0;try {while( (i= reader.read() ) != -1){    System.out.print((char)i);}} catch (IOException e) {e.printStackTrace();}                reader.close();}

 

Writer常用方法:

写入方法:
void write(int c):将参数c的低16位组成字符写入到流中。
void write(char[] buffer):将字符数组buffer中的字符写入到流中。
void write(char[] buffer, int offset, int length):将字符数组buffer中从offset开始的length个字符写入到流中。
void write(String string):将string字符串写入到流中。
void write(String string, int offset, int length):将字符string中从offset开始的length个字符写入到流中。
其他方法:
void close():和OutputStream的close方法类似。
void flush():和OutputStream的flush方法类似。

Writer相关类:

低级Writer类:
CharArrayWriter
StringWriter
PipedWriter
FileWriter
高级Writer类:
BufferedWriter
OutputStreamWriter
PrintWriter:将流转换为文本



try {                                                  FileWriter fw = new FileWriter("mydata.txt");  PrintWriter out = new PrintWriter(fw);         out.print("面朝大海,春暖花开!");             out.close();                                   fw.close();                                   } catch (IOException e) {                              e.printStackTrace();                          }                  


流的几种典型流向:

A-file (bytes)FileInputStream (bytes)DataInputStream (String)
A-File (bytes)FileInputStream (bytes)BufferedInputStream (bytes)DataInputStream   (ints,floats,Strings,others)
(bytes)(bytes)FileReader (chars/Strings)LineNumberReader(chars/strings)
流的基本原则是:高级流与低级流打交道,低级流与I/O设备,文件打叫道,高级流和低级流可以相互交互

特殊的文件流--RandomAccessFile

RandomAccessFile是一种特殊的文件流,可以用它在文件的任何地方查找或者插入数据
RandomAccessFile同时实现了DataInput和DataOutput接口,所以可以用它来读/写文件
构造器:
RandomAccessFile(java.io.File f,String mode)
RandomAccessFile(String file,String mode)

package test3;import java.io.*;public class AppendFile {public static void main(String[] args) {// wirte();read();}public static void read() {try {int i = 0;String record = new String();String toCn = null;RandomAccessFile rf2 = new RandomAccessFile("toAppend.txt", "r");String outCn = null;while ((record = rf2.readLine()) != null) {i++;// 处理中文问题// outCn = record; // 没有处理编码的格式outCn = new String(record.getBytes("ISO8859_1"), "GBK");System.out.println("Line " + i + ":" + outCn);}rf2.close();} catch (Exception e) {e.printStackTrace();}}public static void wirte() {String toAppend = "将发了三分家法律的思";try {int i = 0;String record = new String();String toCn = null;// 处理中文问题toCn = new String(toAppend.getBytes("GBK"), "ISO8859_1");RandomAccessFile rf1 = new RandomAccessFile("toAppend.txt", "rw");rf1.seek(rf1.length());rf1.writeBytes(toCn + "\n");rf1.close();} catch (Exception e) {e.printStackTrace();}}}