Java IO流操作汇总: inputStream 和 outputStream

一、字节流

1. InputStream 和 OutputStream

InputStream 和 OutputStream为各种输入输出字节流的基类,所有字节流都继承这两个基类。

2. FileInputStream 和 FileOutputStream

这两个从字面意思很容易理解,是对文件的字节流操作,也会最常见的IO操作流。

[java]  view plain  copy
  1. /* 
  2.  * 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。 
  3.  */  
  4. public static void readFileByBytes(String inFile, String outFile) {  
  5.     File file = new File(fileName);  
  6.     InputStream in = null;  
  7.     OutputStream out = null;  
  8.     try {  
  9.         byte[] tempbytes = new byte[100];  
  10.         int byteread = 0;  
  11.         in = new FileInputStream(inFile);  
  12.         out = new FileOutputStream(outFile);  
  13.         while ((byteread = in.read(tempbytes)) != -1) {  
  14.             out.write(tempbytes, 0, byteread);  
  15.         }  
  16.     } catch (Exception e1) {  
  17.         e1.printStackTrace();  
  18.     } finally {  
  19.         if (in != null) {  
  20.             try {  
  21.                 in.close();  
  22.             } catch (IOException e1) {  
  23.             }  
  24.             try {  
  25.                 out.close();  
  26.             } catch (IOException e1) {  
  27.             }  
  28.         }  
  29.     }  
  30. }  

3.DataInputStream和DataOutputStream

DataInputStream 是数据输入流,它继承于FilterInputStream。
DataOutputStream 是数据输出流,它继承于FilterOutputStream。
二者配合使用,“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。

[java]  view plain  copy
  1. /** 
  2.  * DataOutputStream的API测试函数 
  3.  */  
  4. private static void testDataOutputStream() {  
  5.     DataOutputStream out = null;  
  6.     try {  
  7.         File file = new File("file.txt");  
  8.         out = new DataOutputStream(new FileOutputStream(file));  
  9.           
  10.         out.writeBoolean(true);  
  11.         out.writeByte((byte)0x41);  
  12.         out.writeChar((char)0x4243);  
  13.         out.writeShort((short)0x4445);  
  14.         out.writeInt(0x12345678);  
  15.         out.writeLong(0x0FEDCBA987654321L);  
  16.         out.writeUTF("abcdefg");  
  17.     } catch (FileNotFoundException e) {  
  18.         e.printStackTrace();  
  19.     } catch (SecurityException e) {  
  20.         e.printStackTrace();  
  21.     } catch (IOException e) {  
  22.         e.printStackTrace();  
  23.     } finally {  
  24.         try {  
  25.             out.close();  
  26.         } catch(IOException e) {  
  27.         }  
  28.     }  
  29. }  
  30.   
  31. /** 
  32.  * DataInputStream的API测试函数 
  33.  */  
  34. private static void testDataInputStream() {  
  35.     DataInputStream in = null;  
  36.     try {  
  37.         File file = new File("file.txt");  
  38.         in = new DataInputStream(new FileInputStream(file));  
  39.   
  40.         System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F));  
  41.         System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF));  
  42.         System.out.printf("readBoolean():%s\n", in.readBoolean());  
  43.         System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte()));  
  44.         System.out.printf("readChar():0x%s\n", charToHexString(in.readChar()));  
  45.         System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort()));  
  46.         System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt()));  
  47.         System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong()));  
  48.         System.out.printf("readUTF():%s\n", in.readUTF());  
  49.     } catch (FileNotFoundException e) {  
  50.         e.printStackTrace();  
  51.     } catch (SecurityException e) {  
  52.         e.printStackTrace();  
  53.     } catch (IOException e) {  
  54.         e.printStackTrace();  
  55.     } finally {  
  56.         try {  
  57.             in.close();  
  58.         } catch(IOException e) {  
  59.         }  
  60.     }  
  61. }  

4.BufferedInputStream 和 BufferedOutputStream

BufferedInputStream是带缓冲区的输入流,它继承于FilterInputStream。默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能。

BufferedOutputStream是带缓冲区的输出流,它继承于FilterOutputStream,能够提高文件的写入效率。

它们提供的“缓冲功能”本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据。

[java]  view plain  copy
  1. public static void readAndWrite(String[] args) {      
  2.     try {  
  3.         BufferedInputStream bis = new BufferedInputStream(new FileInputStream("f:/a.mp3"));  
  4.         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("f:/b.mp3"));  
  5.         byte[] b=new byte[1024];  
  6.         int len=0;  
  7.         while(-1!= (len = bis.read(b, 0, b.length))) {  
  8.             bos.write(b, 0, len);  
  9.         }  
  10.   
  11.     } catch (FileNotFoundException e) {  
  12.         System.out.println("文件找不到");  
  13.         e.printStackTrace();  
  14.     } catch (IOException e) {  
  15.         e.printStackTrace();  
  16.     }finally{  
  17.         if (null! = bos){  
  18.             bos.close();  
  19.         }  
  20.         if (null! = bis){  
  21.             bis.close();  
  22.         }  
  23.     }  
  24. }  

5. ByteArrayInputStream 和 ByteArrayOutputStream

该类从内存中的字节数组中读取数据,它的数据源是一个字节数组,它们分别继承自InputStream 和 OutputStream。

ByteArrayInputStream类的构造方法包括: 
ByteArrayInputStream(byte[] buf)--------参数buf指定字节数组类型的数据源。 
ByteArrayInputStream(byte[] buf, int offset, int length)-----参数buf指定字节数组类型数据源,参数offset指定从数组中开始读取数据的起始下标位置,length指定从数组中读取的字节数。 

[java]  view plain  copy
  1. private static byte[] readWithByteArray(byte[] dataSource) {  
  2.     ByteArrayInputStream in = null;  
  3.     ByteArrayOutputStream out = null;  
  4.       
  5.     try {  
  6.         in = new ByteArrayInputStream(dataSource);  
  7.         out = new ByteArrayOutputStream();  
  8.           
  9.         int len = 0;  
  10.         byte[] buffer = new byte[1024];  
  11.         while ((len = in.read(buffer, 0, buffer.length)) != -1){  
  12.             out.write(buffer, 0, len);  
  13.         }  
  14.         return out.toByteArray();  
  15.           
  16.     } catch (IOException e) {  
  17.         e.printStackTrace();  
  18.     } finally {  
  19.         try {  
  20.             in.close();  
  21.         } catch (IOException e1) {  
  22.         }  
  23.         try {  
  24.             out.close();  
  25.         } catch (IOException e1) {  
  26.         }  
  27.     }  
  28. }  

二、字符流

1. InputStreamReader 和 OutputStreamWriter

 InputStreamReader 和 OutputStreamWriter为各种输入输出字符流的基类,所有字符流都继承这两个基类。实际上,这两个类内部各自持有一个inputStream 和 outputStream对象,相当于是对inputStream 和 outputStream进行了包装,将输入字节流转换成字符流,便于读写操作。

[java]  view plain  copy
  1. /** 
  2.  * 以字符为单位读取文件,常用于读文本,数字等类型的文件 
  3.  */  
  4. public static void readFileByChars(String fileName) {  
  5.     File file = new File(fileName);  
  6.     Reader reader = null;  
  7.     try {  
  8.         System.out.println("以字符为单位读取文件内容,一次读一个字节:");  
  9.         //1. 一次读一个字符  
  10.         reader = new InputStreamReader(new FileInputStream(file));//可以是任意的InputStream类,不一定必须是FileInputStream  
  11.         int tempchar;  
  12.         while ((tempchar = reader.read()) != -1) {  
  13.             if (((char) tempchar) != '\r') {  
  14.                 System.out.print((char) tempchar);  
  15.             }  
  16.         }  
  17.         reader.close();  
  18.     } catch (Exception e) {  
  19.         e.printStackTrace();  
  20.     }  
  21.   
  22.     try {  
  23.         System.out.println("以字符为单位读取文件内容,一次读多个字节:");  
  24.         //2. 一次读多个字符  
  25.         char[] tempchars = new char[30];  
  26.         int charread = 0;  
  27.         reader = new InputStreamReader(new FileInputStream(fileName));  
  28.         while ((charread = reader.read(tempchars)) != -1) {  
  29.             for (int i = 0; i < charread; i++) {  
  30.                 if (tempchars[i] != '\r') {  
  31.                     System.out.print(tempchars[i]);  
  32.                 }  
  33.             }  
  34.         }  
  35.   
  36.     } catch (Exception e1) {  
  37.         e1.printStackTrace();  
  38.     } finally {  
  39.         if (reader != null) {  
  40.             try {  
  41.                 reader.close();  
  42.             } catch (IOException e1) {  
  43.             }  
  44.         }  
  45.     }  
  46. }  

2. FileReader 和 FileWriter

FileReader 和 FileWriter分别继承自 inputStreamReader 和 outputStreamWriter。它是对读取文件操作系统的封装,所有的读写都是直接操作文件系统。因此如果是频繁读写操作,不建议使用FileReader 和 FileWriter,性能将会非常低,这时你需要使用BufferedReader

(1)FileWriter类
构造方法:
FileWriter fw = new FileWriter(String fileName);//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。
FileWriter fw = new FileWriter(String fileName,boolean append);//创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。
主要方法: 

write(char[] buffer, int offset, int count) //将字符数组写入,offset为数组的起始地址,count为需要写入的字符数
void write(String str)  //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。
viod flush() //刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。
viod close() //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。

(2)FileReader类
构造方法:
FileReader fr = new FileReader(String fileName);  //使用带有指定文件的String参数的构造方法。创建该输入流对象。并关联源文件。
主要方法:
int read();   // 读取单个字符。返回作为整数读取的字符,如果已达到流末尾,则返回 -1。
int read(char []cbuf);  //将字符读入数组。返回读取的字符数。如果已经到达尾部,则返回-1。
void close();   //关闭此流对象。释放与之关联的所有资源。

[java]  view plain  copy
  1. public static void readAndWrite() {  
  2.     FileReader fr = null;  
  3.     FileWriter fw = null;  
  4.     try {  
  5.         fr = new FileReader("C:\\my.txt");  
  6.         fw = new FileWriter("D:\\you.txt");  
  7.         //1.读一个字符,写一个字符方法  
  8.         int ch = 0;    
  9.         while ((ch = fr.read()) != -1) {    
  10.             fw.write(ch);    
  11.         }   
  12.           
  13.         //2.读一个数组大小,写一个数组大小方法。  
  14.         char []buf = new char[1024];  
  15.         int len = 0;  
  16.         while((len = fr.read(buf)) != -1){  
  17.             fw.write(buf, 0, len);                
  18.         }  
  19.           
  20.         //3.直接写一个字符串  
  21.         fw.write("hello world!");  
  22.     } catch (Exception e) {  
  23.         System.out.println(e.toString());  
  24.     } finally {  
  25.         if (fr != null)  
  26.             try {  
  27.                 fr.close();  
  28.             } catch (Exception e2) {  
  29.                 throw new RuntimeException("关闭失败!");  
  30.             }  
  31.         if (fw != null){  
  32.             try {  
  33.                 fw.close();  
  34.             } catch (IOException e) {  
  35.                 throw new RuntimeException("关闭失败!");  
  36.             }  
  37.         }  
  38.     }  
  39. }  

3. BufferedReader 和 BufferedWriter

(1)BufferedReader和BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
(2)从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入

[java]  view plain  copy
  1. /** 
  2.  * 以行为单位读取文件,常用于读面向行的格式化文件 
  3.  */  
  4. public static void readWithBufferedReader(String fileName) {  
  5.     File file = new File(fileName);  
  6.     BufferedReader reader = null;  
  7.     try {  
  8.         reader = new BufferedReader(new FileReader(file));  
  9.         String tempString = null;  
  10.         int line = 1;  
  11.         // 一次读入一行,直到读入null为文件结束  
  12.         while ((tempString = reader.readLine()) != null) {  
  13.             System.out.println("line " + line + ": " + tempString);  
  14.             line++;  
  15.         }  
  16.         reader.close();  
  17.     } catch (IOException e) {  
  18.         e.printStackTrace();  
  19.     } finally {  
  20.         if (reader != null) {  
  21.             try {  
  22.                 reader.close();  
  23.             } catch (IOException e1) {  
  24.             }  
  25.         }  
  26.     }  
  27. }  
System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能。例如:
[java]  view plain  copy
  1. public static void readAndWrite() {  
  2.     try {  
  3.         //缓冲System.in输入流  
  4.         //System.in是位流,可以通过InputStreamReader将其转换为字符流  
  5.         BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in));  
  6.         //缓冲FileWriter  
  7.         BufferedWriter bufWriter = new BufferedWriter(new FileWriter("/sdcard/log/test.txt"));  
  8.   
  9.         String input = null;  
  10.         //每读一行进行一次写入动作  
  11.         while(!(input = bufReader.readLine())) {  
  12.             bufWriter.write(input);  
  13.             //newLine()方法写入与操作系统相依的换行字符,依执行环境当时的OS来决定该输出那种换行字符  
  14.             bufWriter.newLine();  
  15.         }  
  16.         bufReader.close();  
  17.         bufWriter.close();  
  18.     } catch(ArrayIndexOutOfBoundsException e) {  
  19.         System.out.println("没有指定文件");  
  20.     } catch(IOException e) {  
  21.         e.printStackTrace();  
  22.     }  
  23. }  

三、 RandomAccessFile 

RandomAccessFile不属于InputStream和OutputStream类系的。实际上,它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。
RandomAccessFile的基本功能有:定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数。实际它和C的fopen()一模一样,都是直接对文件句柄操作。

[java]  view plain  copy
  1. /** 
  2.  * 随机读取文件内容 
  3.  */  
  4. public static void readFileByRandomAccess(String fileName) {  
  5.     RandomAccessFile randomFile = null;  
  6.     try {  
  7.         // 打开一个随机访问文件流,按只读方式  
  8.         randomFile = new RandomAccessFile(fileName, "rw");  
  9.         long fileLength = randomFile.length();  
  10.   
  11.         // 设置读写文件的起始位置  
  12.         randomFile.seek(0);  
  13.   
  14.         // 一次读取多个数据  
  15.         byte[] bytes = new byte[10];  
  16.         int byteread = 0;  
  17.         while ((byteread = randomFile.read(bytes)) != -1) {  
  18.             System.out.write(bytes, 0, byteread);  
  19.         }  
  20.         //一次写入多个数据  
  21.         randomFile.write(bytes);  
  22.           
  23.         // 一次读取单个数据  
  24.         randomFile()  
  25.         // 一次写入单个数据  
  26.         randomFile.writeDouble(47.0001);    
  27.   
  28.     } catch (IOException e) {  
  29.         e.printStackTrace();  
  30.     } finally {  
  31.         if (randomFile != null) {  
  32.             try {  
  33.                 randomFile.close();  
  34.             } catch (IOException e1) {  
  35.             }  
  36.         }  
  37.     }  
  38. }  



猜你喜欢

转载自blog.csdn.net/u010251897/article/details/80648051