首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

【java基础】-(三)javaIO详细阐释

2013-10-07 
【java基础】--(3)javaIO详细阐释1、总的4类字符:Reader 和Writer字节:InputStream和OutputStream2、Reader六

【java基础】--(3)javaIO详细阐释
1、总的4类

字符:Reader 和Writer

字节:InputStream和OutputStream

2、Reader

六个子类BufferedReader,CharArrayReader,FilterReader,InputStreamReader,PipedReader,StringReader

2.1 BufferedReader

为什么用它?

将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的

工作原理?

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

什么时候用?

建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)

示例1:包装InputStreamReader

InputStreamReader又包装System.in

将控制台输入,赋给字符串

 

BufferedReader buf = new BufferedReader(                new InputStreamReader(System.in));        String str = null;        System.out.println("请输入内容");        try{            str = buf.readLine();        }catch(IOException e){            e.printStackTrace();        }        System.out.println("你输入的内容是:" + str);


子类:LineNumberReader
跟踪行号的缓冲字符输入流

2.2 CharArrayReader

工作原理?

把字符数组作为源的输入流的实现

什么时候用?

缓冲字符数组,读取每个字符的时候

示例1:读取字符数组中每个字符并输出

 String strTmp = "abcdefghijklmnopqrstuvwxyz";   int intLen = strTmp.length();  char c[] = new char[intLen];  strTmp.getChars(0,intLen,c,0);
  CharArrayReader input1 = new CharArrayReader(c);  CharArrayReader input2 = new CharArrayReader(c,0,5); 
 int i;  System.out.println("input1 is : ");  while((i=input1.read())!=-1){   System.out.print((char)i);  }  System.out.println();  System.out.println("input2 is : ");  while((i=input2.read())!=-1){   System.out.print((char)i);  }


 

2.3 FilterReader抽象类

子类:PushbackReader

工作原理?

允许将字符推回到流的字符流

unread(char c) 回压一个字符; unread(char c[]) 回压数组 c 中全部字符 
unread(char c[],offset,int n) 回压 c 中从 offset 开始的 n 个字符

为什么用它?

编译原理的一个重要的组成部分叫做词法分析器,就是我上面提到的scanner。对于词法分析程序来说,输入就是源代码,输出就是一个一个的Token(想不出来合适的词),通常词法分析器会一个字符一个字符读取,然后将将这些字符根据一定的规则组成token的序列。有些时候,scanner需要超前读下一个字符才能判断当前的token是否已经结束。例如,int abc=5;这样一个语句,词法分析器要读到=这个字符的时候才能确定abc是一个id,而不是"abc=",这样=已经从输入流中读出来了,但是=又不属于当前的Token,所以要把这个=退回去,这时就要用到pushback。

 

2.4InputStreamReader

是字节流通向字符流的桥梁

要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

 BufferedReader in   = new BufferedReader(new InputStreamReader(System.in));

 

子类:FileReader

工作原理?

用来读取字符文件的便捷类

示例1:读取字符文件并写到数组

路径分隔符:File.separator

 String fileName="D:"+File.separator+"hello.txt";        File f=new File(fileName);        char[] ch=new char[100];        Reader read=new FileReader(f);        int count=read.read(ch);        read.close();        System.out.println("读入的长度为:"+count);        System.out.println("内容为"+new String(ch,0,count));


 

2.5 PipedReader

工作原理?

传送的字符输入流。

什么时候用?

管道输入输出流类主要用于线程之间的通信,不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。

示例1:管道输入输出流类用于线程之间的通信(读管道中数据到字符数组,写到管道中)

两个线程

一个读一个写,都用到管道流,并返回管道流对象

主函数中得到输入输出对象

输出对象与输入对象打通管道 t1.connect(t2);

开启各自线程 s.start(); r.start();

PipedInputStream,PipedOutputStream管道输入输出流类主要用于线程之间的通信,不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。PipedReader,Pipedwriter字符输入输出流类和上面的类似import java.io.*;public class PipedStreamTest {  public static void main(String[] args) {  // TODO Auto-generated method stub        Sender s=new Sender();        Reciever r=new Reciever();        PipedWriter t1=s.getWriter();        PipedReader t2=r.getReader();        try{        t1.connect(t2);        }        catch(Exception e)        {         e.printStackTrace();        }        s.start();        r.start(); }}class Reciever extends Thread{      PipedReader in=new PipedReader();      public PipedReader getReader()      {       return in;      }      public void run()      {       char [] buf=new char[1024];      try{       int len=in.read(buf);       System.out.println("the following messageid:"+'\n'+         new String(buf,0,len));       in.close();      }      catch(Exception e)      {       e.printStackTrace();      }      }}class Sender extends Thread{    private PipedWriter out=new PipedWriter();    public PipedWriter getWriter()          {            return out;        }    public void run()    {     String strInfo=new String("hello,how are you doing?");     try{     out.write(strInfo);     out.close();     }     catch(Exception e)     {      e.printStackTrace();     }    }}


 

2.6StringReader

工作原理?

其源为一个字符串的字符流。文本信息当作内存中的字符一样来处理

什么时候用?

StringReader并不常用,因为通常情况下使用String更简单一些。但是在一些需要Reader作为参数的情况下,就需要将String读入到StringReader中来使用了

示例1:统计单词数

StreamTokenizer(reader);需要reader参数

文件未结束:streamTokenizer.nextToken() != StreamTokenizer.TT_EOF

读到单词:streamTokenizer.ttype == StreamTokenizer.TT_WORD

public void countWordsInAString() {StreamTokenizer streamTokenizer = null;String stringToBeParsed = "The quick brown fox jumped over the lazy dog";StringReader reader = new StringReader(stringToBeParsed);int wordCount = 0;try {streamTokenizer = new StreamTokenizer(reader);while (streamTokenizer.nextToken() != StreamTokenizer.TT_EOF) {if (streamTokenizer.ttype == StreamTokenizer.TT_WORD)wordCount++;}System.out.println("Number of words in file: " + wordCount);} catch (FileNotFoundException ex) {ex.printStackTrace();} catch (IOException ex) {ex.printStackTrace();}}
3、Writer类

7个子类:BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

简要说明下:

PrintWriter可以格式化输出;与PrintStream的区别就是可以自动刷新缓冲

FilterWriter没有子类了

其他的跟reader匹配着用,都差不多

3.1BufferedWriter

工作原理?

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入

示例1:把数据写入文件

File file = new File(filepath);  02         //file.deleteOnExit();  03         file.createNewFile();  04            05         BufferedWriter write = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));  06         write.write("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");  07         write.write("<locals>\n");  08            09            10             write.write("\t</province>\n");  11             System.out.println("===完成省份:"+pro.getValue());  12         }  13         write.write("</locals>");  14         System.out.println("全部完成。。。。。。。。");  15         write.flush();  16         write.close(); 

3.2CharArrayWriter

操作的都是字符数组

工作原理?

此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。

示例1:显示字符内容  

//显示字符内容               array = charArrayWriter.toCharArray();   

示例2:将字符数组内容存回文件

//将字符数组内容存回文件               CharArrayReader charArrayReader = new CharArrayReader(array);                              BufferedWriter bufWriter = new BufferedWriter(                    new FileWriter(file));                              char[] tmp = new char[1];               while(charArrayReader.read(tmp)!=-1)               {                   bufWriter.write(tmp);               }                 charArrayReader.close();               bufWriter.flush();               bufWriter.close();   

3.3FilterWriter

没啥用

3.4OutputStreamWriter

工作原理?

是字符流通向字节流的桥梁

为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:

 示例1:字符串写入控制台

 Writer out   = new BufferedWriter(new OutputStreamWriter(System.out));

示例2:字符串写入文件

File f = new File("d:" + File.separator + "test.txt");          Writer out = null;          out = new OutputStreamWriter(new FileOutputStream(f));// 字节流变为字符流          out.write("hello world");   // 使用字符流输出          out.close(); 
3.5PipedWriter

见2.5PipedReader

3.6PrintWriter

工作原理?

向文本输出流打印对象的格式化表示形式

是一种过滤流,也叫处理流。也就是能对字节流和字符流进行处理

可以对下面几种输出流格式化字符串输出

OutputStream

File

Writer
示例1:格式化

PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

首先,创建一个与指定文件连接的FileWriter。实际上,我们通常会用BufferedWriter将起包装起来用以缓冲输出(......这里面的我省略了)。然后为了格式化把它转换成PrintWriter。

3.7StringWriter

工作原理?

一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。 文本信息当作内存中的字符一样来处理

关闭 StringWriter 无效。此类中的方法在关闭该流后仍可被调用,而不会产生任何 IOException

StringWriter还有一个特点,那就是它能通过GetStringBuilder()方法来获取一个System.Text.StringBuilder对象:

示例1:获取一个System.Text.StringBuilder对象

StringWriter strWriter = new StringWriter();...StringBuilder sb = strWriter.GetStringBuilder();sb.Insert(0, "Hey!! ");Console.WriteLine("-> {0}", sb.ToString());sb.Remove(0, "Hey!! ".Length);


示例2:常规使用

StringWriter strWriter = new StringWriter();strWriter.WriteLine("Don't forget Mother's Day this year...");strWriter.Close();


 

 

 

4、InputStream

9个子类:AudioInputStream,ByteArrayInputStream,FileInputStream,FilterInputStream,InputStream,ObjectInputStream,PipedInputStream,SequenceInputStream,StringBufferInputStream

4.1AudioInputStream

音频输入流是具有指定音频格式和长度的输入流。长度用示例帧表示,不用字节表示。

4.2ByteArrayInputStream

ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用

什么时候使用?

网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去

示例1:内存缓冲区的读写(直接用)

int a=0; 6  int b=1; 7  int c=2; 8  ByteArrayOutputStream bout = new ByteArrayOutputStream(); 9  bout.write(a);10  bout.write(b);11  bout.write(c);12  byte[] buff = bout.toByteArray();13  for(int i=0; i<buff.length; i++)14   System.out.println(buff[i]);15  System.out.println("***********************");16  ByteArrayInputStream bin = new ByteArrayInputStream(buff);17  while((b=bin.read())!=-1) {18   System.out.println(b);


示例2:内存缓冲区的读写(配合DataOutputStream和DataInputStream)

11 byte[] buff = bout.toByteArray();

13 DataInputStream dis = new DataInputStream(bin);

ByteArrayOutputStream bout = new ByteArrayOutputStream(); 6  DataOutputStream dout = new DataOutputStream(bout); 7  String name = "xxy"; 8  int age = 84; 9  dout.writeUTF(name);10  dout.writeInt(age);11  byte[] buff = bout.toByteArray();12  ByteArrayInputStream bin = new ByteArrayInputStream(buff);13  DataInputStream dis = new DataInputStream(bin);14  String newName = dis.readUTF();15  int newAge = dis.readInt();16  System.out.println(newName+":"+newAge);
4.3PipedInputStream类


管道事实上是一个队列 

示例1:管道的输入与输出

import java.io.*;

public class PipedIO //程序运行后将sendFile文件的内容拷贝到receiverFile文件中



public static void main(String args[])



try

{

//构造读写的管道流对象

PipedInputStream pis=new PipedInputStream();

PipedOutputStream pos=new PipedOutputStream();

//实现关联

pos.connect(pis);

//构造两个线程,并且启动。 

new Sender(pos,"c:\\text2.txt").start(); 

new Receiver(pis,"c:\\text3.txt").start(); 

}

catch(IOException e)

{

System.out.println("Pipe Error"+ e);



}

}

//线程发送

class Sender extends Thread



PipedOutputStream pos;

File file;

//构造方法

Sender(PipedOutputStream pos, String fileName)

{

this.pos=pos;

file=new File(fileName);



//线程运行方法

public void run()



try

{

//读文件内容

FileInputStream fs=new FileInputStream(file);

int data;

while((data=fs.read())!=-1)

{

//写入管道始端

pos.write(data);

}

pos.close(); 

}

catch(IOException e)

{

System.out.println("Sender Error" +e);

}

}

}

//线程读

class Receiver extends Thread



PipedInputStream pis;

File file;

//构造方法

Receiver(PipedInputStream pis, String fileName)



this.pis=pis;

file=new File(fileName);



//线程运行

public void run()



try

{

//写文件流对象

FileOutputStream fs=new FileOutputStream(file);

int data;

//从管道末端读

while((data=pis.read())!=-1)

{

//写入本地文件

fs.write(data);

}

pis.close(); 

}

catch(IOException e)

{

System.out.println("Receiver Error" +e);

}

}

}


 

热点排行