IO流——字节流

基本操作与字符流类相同。

但它仅可以操作字符,还可以操作其他媒体文件

字符流的缓冲区是字符数组,字节流的缓冲区是字节数组

例程:

利用字节流输入输出文件。

public void writeObj()
{
     //1.创建字节流对象,用于操作文件
     FileOutputStream fos=new FileOutputStream("bytedeom.txt");
      //写数据,不需要缓冲,直接写入目的地。
     fos.flush(); //无意义  缓冲区对象中是有意义的。
     fos.close();  //关闭资源对象。有意义
}

public void readObj()
{
     //1.创建一个读取流对象,和指定文件关联
     FileInputStream fis=new FileInputStream("bytedeom.txt");
     //一次读入一个字节
     int ch=0;
     while((ch=fis.read())!=-1)
     {
         System.out.println((char)ch);
     }
     
}

 FileInputStream对象的available()方法可以获取取输入文件的字节数大小。

public static void main(String [] args) throws IOException
{
     copy_1();
     copy_2();
     copy_3();
}

public void copy_1() throws IOException
{
    FileInputStream fis=new FileInputStream("c:\0.mp3");
    FileOutputStream fos=new FileOutputStream("C:\1.mp3");
    byte[] buf=new byte[1024];
    int len=0;
    while ((len=fis.read(buf))!=-1)
    { 
         fos.write(buf,0,len);
    }
     fos.close();
     fis.close();
}

public void copy_2() throws IOException
{
    FileInputStream fis=new FileInputStream("c:\0.mp3");
    BufferedInputStream bufis=new BufferedInputStream(fis);
    FileOutputStream fos=new FileOutputStream("C:\1.mp3");
    BufferedOutputStream bufos=new BufferedOutputStream(fos);
    int ch=0;
    while ((ch=bufis.read()!=-1)
    { 
         bufos.write(ch);
         bufos.flush();
    }
     bufos.close();
     bufis.close();
}

public void copy_3() throws IOException  //缓冲数组可能太大
{
    FileInputStream fis=new FileInputStream("c:\0.mp3");
    FileOutputStream fos=new FileOutputStream("C:\1.mp3");
    byte[] buf=new byte[fis.available()];
    int len=0;
    while ((len=fis.read(buf))!=-1)
    { 
         fos.write(buf,0,len);
    }
     fos.close();
     fis.close();
}

public void copy_4() throws IOException   //非常慢
{
    FileInputStream fis=new FileInputStream("c:\0.mp3");
    FileOutputStream fos=new FileOutputStream("C:\1.mp3");
    int ch=0;
    while ((ch=fis.read())!=-1)
    { 
         fos.write(ch);
    }
     fos.close();
     fis.close();
}

用字符流读图片文件,行吗?不行,因为字符流是按字符数据读图片文件,然后查编码表,读图片文件有可能查不到编码表内容。

读入一个键盘录入的数据,并打印在控制台上。

键盘本身就是一个标准的输入设备,对于java而言,对于这种输入设备都有对应的对象。

public static void readKey() throws IOExcepton
{
     InputStream in=System.in;//键盘输入是字节流
     int  ch=0;
     while((ch=in.read())!=-1)
     {
           System.out.println(ch);
     }
     //in流不能关,一关键盘就无法输入,系统流是不需要关的。
}
public static void readKey2() throws IOException
{
      /*
      *获取键盘录入的数据
      *并将数据变成大写,显示在控制台上
      *如果用户输入的是over,结束键盘录入
      */
       StringBuilder sb=new StringBuilder();
       InputStream in=System.in;
       int ch=0;
       while((ch=in.read())!=-1)
       {
           if (ch==13)
                continue;
           if (ch==10)
           {
                  String tmp=sb.toString();
                  if (tmp.equals("over"))
                        break;
                 System.out.println(tmp.toUpperCase());
                 sb.delete(0.sb.length());
           }
           else
           {
                 sb.add((char)ch);
            }
       }
}

字节流转字符流实例

public static void exam()
{
         //字节流
           InputStream in=system.in;
        //InputStreamReader是字节流通向字符流的桥梁,它用指定的编码表为字节解码     
        InputStreamReader isr=new InputStreamReader(in);  
        //字符流
        BufferedReader bufr=new BufferedReader(isr);
        String line=null;
        while((line=bufr.readLine())!=null)
        {
             if ("over".equals(line))
                 break;
             System.out.println(line.toUpperCase());
        }
}

 字符流通向字节流的桥梁是OutputStreamWriter,FileWriter是操作文本文件的类,它的父类就是OutperStreamWriter类的子类。

public static void exam()
{
         //字节流
           InputStream in=system.in;
        //InputStreamReader是字节流通向字符流的桥梁,它用指定的编码表为字节解码     
        InputStreamReader isr=new InputStreamReader(in);  
        //字符流
        BufferedReader bufr=new BufferedReader(isr);
//以上三句可简化为: BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
//字节流 OutputStream out=System.out; OutputStreamWriter osw=new OutputStreamWriter(out); BufferedWriter bufw=new BufferedWriter(osw);
//以上三句可简化为:BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out)); String line
=null; while((line=bufr.readLine())!=null) { if ("over".equals(line)) break; // bufw.write(line.toUpperCase()+" "); //字符转字节,并输出。 //osw.flush(); bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush(); } }

 分析如下:

IO流——字节流

 转换流:

InputStreamReader:字节到字符的桥梁,解码

OutputStreamWriter:字符到字节的桥梁,编码

流的操作规律:

想要知道开发时用到哪些对象,只要通过四个明确即可:

1.明确源和目的:汇

          源:InputStream、Reader

         目的:OutputStream 、Writer

2.明确数据是否是纯文本数据

         源:是,Reader;否,InputStream

        目的:是,Writer;否,OutputStream

3.明确具体的设备

        源设备:

               硬盘:File

               键盘:System.in

              内存:数组

              网络:Socket流

      目的设备:

             硬盘:File

            控制台:System.out

            内存:数组

            网络:Socket流

4.是否需要其他额外功能

          (1)是否需要高效(缓冲区)

              是,就加上Buffer。

             BufferedReader bufr=new BufferedReader(new FileReader("a.txt"));

             BufferedWriter bufw=new BufferedWriter(new FileWriter("b.txt"));

 将一个中文字符串按照指定的编码表写入到一个文本文件中。

public static void writeText_1()
{
        //FileWriter只能用默认码表,不能指定
        //FileWriter其实就是转换流指定了本机默认码表的体现。
        FileWriter w=new FileWriter("gbk_1.txt");
        //字符串默认的是本地默认码表,中文平台一般为GBK
        //java默认码表为Unicode码表,一个字符2个字符
        //后扩展为utf-8,字符可能1个字节,2个字符,3个字节
        fw.write("你好");//默认GBK
        fw.close();
}

public static void writeText_2()
{     
        //OutputStreamWriter是FileWriter的父类,它可以指定码表
        OutputStreamWriter osw=new OutputStreamWriter(new FileOuptStream("gbk_2.txt"),"GBK");//码表名称不分大小写
        osw.write("你好");
        osw.close();
}

同理,读取文本文件时也要指定相应的码表。

可以看出,能指定编码表,也是转换流的一个重要的功能。

什么时候使用转换流呢?

1. 源或目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换流作为桥梁。

2.一旦操作文本涉及到具体的指定编码表时,必须使用转换流。