13.2.1面向字节的输入流

image.png

1. 类InputStream介绍

public int read() :读一个字节
public int read(byte b[]):读多个字节到字节数组 ,方法返回结果为实际读到的字节数
public int read(byte[] b, int off, int len) : 从输入流读指定长度的数据到数组,数据从数组的off处开始存放。
public long skip(long n) :指针跳过n个字节,定位输入位置指针的方法
public void mark():在当前位置指针处做一标记
public void reset() :将位置指针返回标记处
public void close() :关闭流

  1. 将键盘输入的十六进制数转化为十进制---直接转化----> Integer.parseInt(s,16);
  2. import java.io.*;
  3. public class Convert{
  4. public static void main(String args[ ]) {
  5. try {
  6. char ch=' '; //存放输入的字符
  7. int x=0; //存放转换后的数字
  8. long d=0; //存放转换的十进制数
  9. System.out.print("输入一个十六进数:");
  10. ch=(char)System.in.read( ); //读一个字符 (char)强制转换,read读入的整形
  11. while (ch!='\r') {
  12. switch (ch) {
  13. case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
  14. x=(ch-'0');
  15. break;
  16. case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
  17. x=(ch-'A')+10;
  18. break;
  19. case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
  20. x=(ch-'a')+10;
  21. break;
  22. default:
  23. System.out.println("非法符号");
  24. System.exit(0);
  25. }
  26. d = d*16 + x; //转换结果拼接
  27. ch=(char)System.in.read();
  28. } // while 结尾
  29. System.out.println("十进制="+d);
  30. } catch (IOException e) { }
  31. }
  32. }
  33. 运行示例:
  34. 输入一个十六进数:2a
  35. 十进制=42

2.类InputStream的子类的使用

类名 构造方法的主要参数 功能描述
ByteArrayInputStream 字节数组 以字节数组作为输入源。
FileInputStream 类File的对象或字符串表示的文件名 以文件作为数据源。
PipedInputStream PipedOutputStream的对象 与另一输出管道相连,读取写入到输出管道中的数据,用于程序中线程间通信
FilterInputStream InputStream的对象 用于装饰另一输入流以提供对输入数据的附加处理功能,子类见表13-2
SequeueInputStream 系列InputStream的对象 将两个其他流首尾相接,合并为一个完整的输入流。
ObjectInputStream InputStream的对象 用于从输入流读取串行化对象。可实现轻量级对象持久性。

类FilterInputStream的常见子类

类名 功能描述
BufferedInputStream 为所装饰的输入流提供缓冲区的功能,以提高输入数据的效率
DataInputStream 为所装饰的输入流提供数据转换的功能,可从数据源读取各种基本类型的数据。
LineNumberInputStream 为文本文件输入流附加行号
PushbackInputStream 提供回压数据的功能,可以多次读同样数据
  1. import java.io.*;
  2. public class DisplayFile
  3. {
  4. public static void main(String args[])
  5. {
  6. try
  7. {
  8. FileInputStream infile = new FileInputStream(args[0]);
  9. int byteRead = infile.read(); 以字节为单位访问
  10. while (byteRead!=-1) {
  11. System.out.print((char)byteRead);
  12. byteRead = infile.read();
  13. }
  14. }catch(ArrayIndexOutOfBoundsException e){
  15. System.out.println("需要提供一个文件名作为命令行参数 ");
  16. }catch(FileNotFoundException e) {
  17. System.out.println("file not find! ");
  18. }catch(IOException e) { }
  19. }
  20. }

FileInputStream infile = new FileInputStream(args[0]);
BufferedInputStream buin=new BufferedInputStream(infile); 创建输入流包装
相当于:BufferedInputStream buin=new BufferedInputStream(new FileInputStream(args[0]));

String str=new String(buffer,0,byteRead); 读取的字节转换为字符
System.out.print(str);
相当于:System.out.print((char)byteRead);将字节转化成字符输出

  1. import java.io.*;
  2. public class DisplayFile
  3. {
  4. public static void main(String args[])
  5. {
  6. try
  7. {
  8. FileInputStream infile = new FileInputStream(args[0]); 从命令行获取要显示的文件名
  9. BufferedInputStream buin=new BufferedInputStream(infile); 创建输入流
  10. byte[] buffer=new byte[64];
  11. int byteRead = buin.read(buffer);
  12. while (byteRead!=-1)
  13. { //判断是否读到文件的末尾
  14. String str=new String(buffer,0,byteRead); 读取的字节转换为字符
  15. System.out.print(str);
  16. //System.out.print((char)byteRead);
  17. byteRead = buin.read(buffer); read()方法读到文件结尾返回-1,读取文件时一个一个字节读入
  18. }
  19. buin.close();
  20. }catch(ArrayIndexOutOfBoundsException e) {
  21. System.out.println("需要提供一个文件名作为命令行参数 ");
  22. }catch(FileNotFoundException e) {
  23. System.out.println("file not find! ");
  24. }catch(IOException e) { }
  25. }
  26. }

数据输入流DataInputStream

  • 实现各种基本类型数据的输入处理
  • 实现DataInput接口
    • byte readByte()
    • boolean readBoolean()
    • short readShort()
    • char readChar()
    • int readInt()—-读整数
    • long readLong()
    • float readFloat()
    • double readDouble()

//以上为:以数据类型为单位访问数据

  • String readUTF()---读字符串

    13.2.2 面向字节的输出流

    image.png
    面向字节输出流的继承层次

    类OutputStream的方法

  • void write(int b) :将参数b的低字节写入输出流
  • void write(byte b[]) :将字节数组全部写入输出流
  • void write(byte b[],int off, int len) : 将字节数组从off位置开始的len个字节写入输出流
  • void flush() :强制将缓冲区数据写入输出流对应的外设
  • void close() :关闭输出流

    以字节为单位写入数据——-文件输入/输出流的使用

    1. import java.io.*;
    2. public class BigToSmall {
    3. public static void main(String args[])
    4. {
    5. int number=0;
    6. final int size=Integer.parseInt(args[1]); 小文件大小
    7. byte[] b = new byte[size];
    8. try
    9. {
    10. FileInputStream infile = new FileInputStream(args[0]); 大文件名称
    11. while (true)
    12. {
    13. FileOutputStream outfile = new FileOutputStream("file"+number); 小文件的名称
    14. number++;
    15. int byteRead = infile.read(b); 以字节为单位读数据
    16. if (byteRead==-1)
    17. break;
    18. outfile.write(b,0,byteRead); 以字节为单位写入数据
    19. outfile.close(); 写完之后必须关闭文件
    20. }
    21. }catch(IOException e) { }
    22. }
    23. }
    24. 运行程序输入两个参数:1、需拆分的大文件名 2、小文件的大小。分拆的小文件名为file0file1file2.....
    25. 注意:将数据写入文件用write(b,0,byteRead)方法保证将当前读到的数据写入文件;不使用write(b)因为最后一个文件会更小

    基本数据类型数据的读写问题

    类DataOutputStream实现各种类型数据的输出处理,它实现了DataOutput接口,在该接口中定义了基本数据类型数据的输出方法

    • void writeByte(int x) //参数x的8个低位
    • void writeBytes(String x) //按字节顺序写入
    • void writeChar(int x) //一个char值(2字节)写入
    • void writeBoolean(boolean x)
    • void writeChars(String x) //按字符顺序写入
    • void writeInt(int x)
    • void writeLong(long x)
    • void writeFloat(float x)
    • void writeDouble(double x)
    • void writeUTF(String x)//使用UTF-8编码

找出10~100之间的所有姐妹素数,写入到文件中。所谓姐妹素数是指相邻两个奇数均为素数

  1. import java.io.*;
  2. public class FindSisterPrime
  3. {
  4. public static boolean isPrime(int n)
  5. {
  6. for (int k=2;k<=Math.sqrt(n);k++)
  7. {
  8. if (n%k==0)
  9. return false;
  10. }
  11. return true;
  12. }
  13. public static void main(String[] args)
  14. {
  15. try
  16. {
  17. FileOutputStream file = new FileOutputStream("x.dat"); 创建一个文件输出流,文件不存在则自动生成
  18. DataOutputStream out=new DataOutputStream(file); FileOutputStream包装,创建一个DataOutputStream流,利用该流向文件写入各种类型的数据
  19. for (int n=11;n<100;n+=2)
  20. {
  21. if (isPrime(n)&&isPrime(n+2))
  22. {
  23. out.writeInt(n); DataOutputStreamwriteInt方法,写入整数
  24. out.writeInt(n+2);
  25. }
  26. }
  27. out.close();
  28. }catch (IOException e) { };
  29. }
  30. }
  31. 结果输出将显示乱码,原因在于该文件中的数据不是文本格式数据,想要获取数据,需要以输入流的方式访问文件
  32. //获取数据
  33. import java.io.*;
  34. public class OutSisterPrime
  35. {
  36. public static void main(String[] arguments)
  37. {
  38. try
  39. {
  40. FileInputStream file = new FileInputStream("x.dat");
  41. DataInputStream in=new DataInputStream(file);
  42. while(true)
  43. {
  44. int n1=in.readInt(); 以整数为单位读
  45. int n2=in.readInt();
  46. System.out.println(n1+","+n2);
  47. }
  48. }catch (EOFException e) { }catch (IOException e) { }
  49. }
  50. }
  51. while(true)遇到文件结束抛出EOFException异常。
  52. 可改为:while(in.available()!=0),返回要读取的字节长度。
  53. 思考:将20个随机整数写入文件x.dat
  54. public class test1
  55. {
  56. public static void main(String args[])
  57. {
  58. try
  59. {
  60. DataOutputStream out = new DataOutputStream(new FileOutputStream("x.dat"));
  61. for(int j=1; j<=20; j++)
  62. {
  63. int x=(int)(Math.random()*100);
  64. out.writeInt(x); 输出是乱码
  65. }
  66. out.close();
  67. }catch(IOException e);
  68. }
  69. }