zoukankan      html  css  js  c++  java
  • Java知多少(70)面向字节流的应用

    文件输入输出流

    文件输入输出流 FileInputStream 和 FileOutputStream 负责完成对本地磁盘文件的顺序输入输出操作。

    【例 10-5】通过程序创建一个文件,从键盘输入字符,当遇到字符“#”时结束,在屏幕上显示该文件的所有内容。

     1 【例 10-5】通过程序创建一个文件,从键盘输入字符,当遇到字符“#”时结束,在屏幕上显示该文件的所有内容。
     2 //********** ep10_5.java **********
     3 import java.io.*;
     4 class ep10_5{
     5     public static void main(String args[]){
     6         char ch;
     7         int data;
     8         try{
     9             FileInputStream a=new FileInputStream(FileDescriptor.in);  //创建文件输入流对象
    10             FileOutputStream b=new FileOutputStream("ep10_5");  //创建文件输出流对象
    11             System.out.println("请输入字符,以#号结束:");
    12             while((ch=(char)a.read())!='#'){
    13                 b.write(ch);
    14             }
    15             a.close();
    16             b.close();
    17             System.out.println();
    18             FileInputStream c=new FileInputStream("ep10_5");
    19             FileOutputStream d=new FileOutputStream(FileDescriptor.out);
    20             while(c.available()>0){
    21                data=c.read();
    22                d.write(data);
    23            }
    24            c.close();d.close();
    25        }
    26        catch(FileNotFoundException e){
    27           System.out.println("找不到该文件!");
    28        }
    29        catch(IOException e){}
    30     }
    31 }

    运行后在程序目录建立一个名称为 ep10_5 的文件,运行结果如图 10-8 所示:

    图 10-8   例 10_5 运行结果
    图 10-8  例 10_5 运行结果


    FileDescriptor 是 java.io 中的一个类,该类不能实例化,其中包含三个静态成员:in、out 和err,分别对应于标准输入流、标准输出流和标准错误流,利用它们可以在标准输入输出流上建立文件输入输出流,实现键盘输入或屏幕输出操作。

    【例 10-6】实现对二进制图形文件(.gif)的备份。

     1 【例 10-6】实现对二进制图形文件(.gif)的备份。
     2 //********** ep10_6.java **********
     3 import java.io.*;
     4 class ep10_6{
     5     public static void main(String args[]) throws IOException{
     6         FileInputStream a=new FileInputStream("ep10_6.gif");
     7         FileOutputStream b=new FileOutputStream("ep10_6_a.gif");
     8         System.out.println("文件的大小为:"+a.available());
     9         byte c[]=new byte[a.available()];
    10         a.read(c);  //将图形文件读入数组
    11         b.write(c);  //将数组中的数据写入到新文件中
    12         System.out.println("文件已经被更名复制!");
    13         a.close();
    14         b.close();
    15     }
    16 }

    运行后在程序目录备份了一个名称为 ep10_6_a.gif 的文件,运行结果如图 10-9 所示:


    图 10-9  例 10_6 运行结果

    过滤流

    FilterInputStream 和 FileOutputStream 是 InputStream 和 OutputStream 的直接子类,分别实现了在数据的读、写操作的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换。

    常用的两个过滤流是数据输入流 DataInputStream 和数据输出流 DataOutputStream。其构造方法为:
        DataInputStream(InputStream in);  //创建新输入流,从指定的输入流 in 读数据
        DataOutputStream(OutputStream out);  //创建新输出流,向指定的输出流 out 写数据

    由于 DataInputStream 和 DataOutputStream 分别实现了 DataInput 和 DataOutput 两个接口(这两个接口规定了基本类型数据的输入输出方法)中定义的独立于具体机器的带格式的读写操作,从而实现了对不同类型数据的读写。由构造方法可以看出,输入输出流分别作为数据输入输出流的构造方法参数,即作为过滤流必须与相应的数据流相连。

    DataInputStream 和 DataOutputStream 类提供了很多个针对不同类型数据的读写方法,具体内容读者可参看 Java 的帮助文档。

    【例 10-7】将三个 int 型数字 100,0,-100 写入数据文件 ep10_6.dat 中。

     1 【例 10-7】将三个 int 型数字 100,0,-100 写入数据文件 ep10_6.dat 中。
     2 //********** ep10_7.java **********
     3 import java.io.*;
     4 class ep10_7{
     5     public static void main(String args[]){
     6         String fileName="ep10_7.dat";
     7         int value1=100,value2=0,value3=-100;
     8         try{
     9             //将 DataOutputStream 与 FileOutputStream 连接输出不同类型的数据
    10             DataOutputStream a=new DataOutputStream(new FileOutputStream(fileName));
    11             a.writeInt(value1);
    12             a.writeInt(value2);
    13             a.writeInt(value3);
    14             a.close();
    15         }
    16         catch(IOException i){
    17             System.out.println("出现错误!"+fileName);
    18         }
    19     }
    20 }

    运行后在程序目录中生成数据文件 ep10_7.dat,用文本编辑器打开后发现内容为二进制的:

    00 00 00 64 00 00 00 00 FF FF FF 9C。

    【例 10-8】读取数据文件 ep10_6.dat 中的三个 int 型数字,求和并显示。

     1 【例 10-8】读取数据文件 ep10_6.dat 中的三个 int 型数字,求和并显示。
     2 //********** ep10_8.java **********
     3 import java.io.*;
     4 class ep10_8{
     5     public static void main(String args[]){
     6         String fileName="D:\myjava/ep10_7.dat";
     7         int sum=0;
     8         try{
     9             DataInputStream a=new DataInputStream(new BufferedInputStream(new FileInputStream(fileName)));
    10             sum+=a.readInt();
    11             sum+=a.readInt();
    12             sum+=a.readInt();
    13             System.out.println("三个数的和为:"+sum);
    14             a.close();
    15         }
    16         catch(IOException e){
    17             System.out.println("出现错误!"+fileName);
    18         }
    19     }
    20 }

    运行结果:

    三个数的和为:0

    readInt 方法可以从输入输出流中读入 4 个字节并将其作为 int 型数据直接参与运算。由于已经知道文件中有 3 个数据,所以可以使用 3 个读入语句,但若只知道文件中是 int 型数据而不知道数据的个数时该怎么办呢?因为 DataInputStream 的读入操作如遇到文件结尾就会抛出 EOFException 异常,所以可将读操作放入 try 中。

    1 try{
    2     while(true)
    3     sum+=a.readInt();
    4 }
    5 catch(EOFException e){
    6     System.out.pritnln("三个数的和为:"+sum);
    7     a.close();
    8 }

    EOFException 是 IOException 的子类,只有文件结束异常时才会被捕捉到,但如果没有读到文件结尾,在读取过程中出现异常就属于 IOException。


    【例 10-9】从键盘输入一个整数,求该数的各位数字之和。

     1 【例 10-9】从键盘输入一个整数,求该数的各位数字之和。
     2 //********** ep10_9.java **********
     3 import java.io.*;
     4 class ep10_9{
     5     public static void main(String args[]) throws IOException{
     6         DataInputStream a=new DataInputStream(System.in);
     7         System.out.print("请输入一个整数:");
     8         int b=a.readInt();
     9         int sum=0;
    10         int c=b;
    11         while(c>0){
    12             int d=c%10;  //取最低位
    13             c=c/10;  //去掉最低位
    14             sum=sum+d;  //累加各位之和
    15         }
    16         System.out.println(b+"的各位数字之和="+sum);
    17     }
    18 }

    运行结果:

    请输入一个整数:26
    842403082 的各位数字之和=31

    需要注意的是,输入的数据 26 为变成了 842403082,原因在于输入数据不符合基本类型数据的格式,从键盘提供的数据是字符的字节码表示方式,若输入 26,只代表 2 和 6 两个字符的字节数据,而不是代表整数 26 的字节码。

    若要从键盘得到整数需要先读取字符串,再利用其他方法将字符串转化为整数。

    标准输入输出

    System.in、System.out、System.err 这 3 个标准输入输流对象定义在 java.lang.System 包中,这 3 个对象在 Java 源程序编译时会被自动加载。

    1. 标准输入:标准输入 System.in 是 BufferedInputStream 类的对象,当程序需要从键盘上读入数据时,只需要调用 System.in 的 read()方法即可,该方法从键盘缓冲区读入一个字节的二进制数据,返回以此字节为低位字节,高位字节为 0 的整型数据。
    2. 标准输出:标准输出 System.out 是打印输出流 PrintStream 类的对象。PrintStream 类是过滤输出流类 FilterOutputStream 的一个子类,其中定义了向屏幕输出不同类型数据的方法print()和 println()。
    3. 标准错误输出:System.err 用于为用户显示错误信息,也是由 PrintStream 类派生出来的错误流。Err 流的作用是使 print()和 println()将信息输出到 err 流并显示在屏幕上,以方便用户使用和调试程序。


    【例 10-10】输入一串字符显示出来,并显示 System.in 和 System.out 所属的类。

     1 【例 10-10】输入一串字符显示出来,并显示 System.in 和 System.out 所属的类。
     2 //********** ep10_10.java **********
     3 import java.io.*;
     4 class ep10_10{
     5     public static void main(String args[]){
     6         try{
     7             byte a[]=new byte[128];  //设置输入缓冲区
     8             System.out.print("请输入字符串:");
     9             int count =System.in.read(a);  //读取标准输入输出流
    10             System.out.println("输入的是:");
    11             for(int i=0;i<count;i++)
    12                System.out.print(a[i]+"");  //输出数组元素的 ASCII 值
    13             System.out.println();
    14             for(int i=0;i<count-2;i++)  //不显示回车和换行符
    15                 System.out.print((char)a[i]+"");  //按字符方式输出元素
    16             System.out.println();
    17             System.out.println("输入的字符个数为:"+count);
    18             Class InClass=System.in.getClass();
    19             Class OutClass=System.out.getClass();
    20             System.out.println("in 所在的类为:"+InClass.toString());
    21             System.out.println("out 所在的类为:"+OutClass.toString());
    22         }
    23         catch(IOException e){}
    24     }
    25 }

    运行结果如图 10-10 所示:

    图 10-10  例 10_10 运行结果
    图 10-10  例 10_10 运行结果


    需要注意的是,输入了 3 个字符按回车后,输出的结果显示为 5 个字符。这是由于 Java 中回车被当作两个字符,一个是 ASCⅡ为 13 的回车符,一个是值为 10 的换行符。程序中 getClass()和 ToString()是 Object 类的方法,作用分别是返回当前对象所对应的类和返回当前对象的字符串表示。

    系列文章:
  • 相关阅读:
    程序员需要看的书
    linux常见命令实践.
    数据库使用简单总结
    剑指offer【书】之简历抒写
    面试中自己项目和你应该问的问题环节总结
    Matlab近期用到的函数(持续更新)
    排序-快速排序算法
    系统运维-hub, repeater, switch, router初览
    C++基础-位运算
    排序-冒泡排序
  • 原文地址:https://www.cnblogs.com/Coda/p/4521357.html
Copyright © 2011-2022 走看看