zoukankan      html  css  js  c++  java
  • Java IO对文件的操作

    InputStream.read()

    返回int ,且范围为0到255间int值 ,从输入流读取下一个数据字节,它是以字节为单位来读的,即每次只读取一个字节内容 ,读取后面三前面补三个字节的0,这样读取出来的结果就永远为正,且为0到255间的数。如果因已到达流末尾而没有可用的字节,则返回值-1 。用于进制文件的读取。 


    如果我们读取的是二进制文件,如图片声音文件时,我们应该使用如下两种方式来读取:
    第一种 : 还是使用InputStream.read(),方法来读取,只不过我们把int型强制转换byte型即可,这样在转换的过程中,会丢弃前三个字节所补的 零,最终得到从流中读取的真实的编码。但如果这样直接通过read()方法读取,而不是通过read(byte[] b)时,我们判断流是否结尾,最好使用available()方法来判断,当然也可以使用直接比较读出的结果是否为-1,但是要注意的是我们不能在读取后强转成byte型后再判断,因为二进制文件有可能有-1的编码。


    第二种 :使用InputStream.read(byte[] b)来接收,因为这样不会有byte到int提升的过程,byte数组b里存储的就是真实的编码。如果read(byte[] b)读取到流的尾,则返回-1,所以我们直接判断返回的读取子节数就可知道流是否结束。

    OutputStream.write(int b)

    将指定的字节写入此输出流。write 的规定是:向输出流写入一个字节。要写入的字节是参数b的八个低位。b 的24个高位将被忽略。此方法能向文件中写入负数编码,即可写入二进制流的文件,如声音、图片等文件。

    我们再来看看Reader与Writer字符流相应方法:

    Reader.read

    Reader.read:读取单个字符。在有可用字符、发生 I/O 错误或者已到达流的末尾前,此方法一直阻塞。范围在 0 到 65535 之间 (0x00-0xffff),实质上读取出来的就是一个char型,即为Unicode编码了。如果已到达流的末尾,则返回 -1

    Writer. write(int c)

    Writer. write(int c):写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。

    从上面可以看出是两类字符流,一种是字节流,另一种是字符流,如果我们读取/写 入的是一个二进制文件,则使用字节流InputStream.read/OutputStream.write;如果我们读取/写入的是一个字符文件,则 使用字符流Reader.read/Writer.write会很方便,当然字符流也可以使用字节流来操作,只是在某些情况下不是很方便。

    Java代码  收藏代码
      1. import java.io.File;  
      2. import java.io.FileInputStream;  
      3. import java.io.FileNotFoundException;  
      4. import java.io.FileOutputStream;  
      5. import java.io.IOException;  
      6.   
      7. import junit.framework.TestCase;  
      8.   
      9. public class TestBinaryStreamReadWrite extends TestCase {  
      10.     /* 
      11.      * 写二进制文件(如声音文件)时,只能使用字节流写。outputStream.write方法 只写入最低八位, 
      12.      * 前三字节会丢弃掉,只存储最后一字节 
      13.      */  
      14.     public void testCreateByteFile() {  
      15.         try {  
      16.             FileOutputStream fo = new FileOutputStream("e:/tmp/tmp");  
      17.             byte b = -1;  
      18.             //向文件写两个-1,没有编码为-1的字符,所以创建出的文件为纯二进制文件  
      19.             fo.write(b);  
      20.             fo.write(b);  
      21.             fo.close();  
      22.         } catch (FileNotFoundException e) {  
      23.             e.printStackTrace();  
      24.         } catch (IOException e) {  
      25.             e.printStackTrace();  
      26.         }  
      27.     }  
      28.   
      29.     /* 
      30.      * InputStream.read方式是读取一个字节内容后,以int型返回,在这之间有一个转换的过程:当读 
      31.      * 取一个字节内容后,会在这八位二进制前再补24位二进制的0,所以最后返回的字节编码为正数,永不 
      32.      * 会为负数,且范围为0-255间的整数。这样如果使用read方法读取二进制文件时,读出的编码是整数, 
      33.      * 原本可能为负编码,最终显示成了正编码。为了确保得到正确的原本二进制编码,在读取后只能强制转 
      34.      * 换成byte型,或使用read(byte b)方式来读取。 
      35.      */  
      36.     public void testReadEncodeError() {  
      37.         try {  
      38.             FileInputStream fi = new FileInputStream("e:/tmp/tmp");  
      39.             //read方ifc读取的一个字节内容,返回0到255范围内的int字节值,如果因已到达流  
      40.             //末尾而没有可用的字节,则返回值-1  
      41.   
      42.             int readInt = fi.read();  
      43.             //如果已到达文件末尾,则返回-1。虽然的文件中的每个字节的内容都是-1,但读出来的不是-1,  
      44.             //所以第二个字节也能输出,而不会出现只能读取第一个字节,第二个字节读不出的问题  
      45.             while (readInt != -1) {  
      46.                 //输入两个255,但输入的编码是错误的,应该为-1才对  
      47.                 System.out.println(readInt);  
      48.                 //读下一字节  
      49.                 readInt = fi.read();  
      50.             }  
      51.             fi.close();  
      52.         } catch (FileNotFoundException e) {  
      53.             e.printStackTrace();  
      54.         } catch (IOException e) {  
      55.             e.printStackTrace();  
      56.         }  
      57.     }  
      58.   
      59.     /* 
      60.      * 使用InputStream.read读取出的编码如果经过强转换byte型后,我们就不能再使用 readByte  
      61.      * != -1 来判断文件流是否结束了,因为如果为二进制文件,读出的编码就有 为负的,总之,如果读取 
      62.      * 的是二进制文件,就不能直接使用真实编码与-1比较,只能使用available或通InputStream.read 
      63.      * (byte[] b)方法返回的所读字节数来判断 
      64.      */  
      65.     public void testAvailable() {  
      66.         try {  
      67.             File file =  new File("e:/tmp/tmp");  
      68.             FileInputStream fi = new FileInputStream(file);  
      69.             System.out.println("available实质上与file的length相同:" +file.length());  
      70.             //当使用read方法读取出的编码后经强转byte后,不能使用 (byte) fi.read() != -1 来  
      71.             //判断是文件流是否结束,这里我们只能使用available来判断是否达文件尾  
      72.             while (fi.available() > 0) {  
      73.                 System.out.println("available=" + fi.available());  
      74.                 //使用read()方法读取字节内容的编码后,只能强转byte型才能得到真实的编码  
      75.                 System.out.println((byte) fi.read());  
      76.             }  
      77.             fi.close();  
      78.         } catch (FileNotFoundException e) {  
      79.             e.printStackTrace();  
      80.         } catch (IOException e) {  
      81.             e.printStackTrace();  
      82.         }  
      83.     }  
      84.   
      85.     /* 
      86.      * 读取二进制文件(如图片)而非字符文件时,除了使用read()读取强转byte型,使用 InputStream. 
      87.      * read(byte[] b)是最好的方式,此时使用读取返回的字节数来判断是否读完 
      88.      */  
      89.     public void testReadByByteArr() {  
      90.         try {  
      91.             FileInputStream fi = new FileInputStream("e:/tmp/tmp");  
      92.             byte[] byteArr = new byte[1024];  
      93.             //读取的字节数  
      94.             int readCount = fi.read(byteArr);  
      95.             //如果已到达文件末尾,则返回-1  
      96.             while (readCount != -1) {  
      97.                 for (int i = 0; i < readCount; i++) {  
      98.                     System.out.println(byteArr[i]);  
      99.                 }  
      100.                 readCount = fi.read(byteArr);  
      101.             }  
      102.             fi.close();  
      103.   
      104.         } catch (FileNotFoundException e) {  
      105.             e.printStackTrace();  
      106.         } catch (IOException e) {  
      107.             e.printStackTrace();  
      108.         }  
      109.     }  
      110.   
      111.     /* 
      112.      * 使用InputStream.read读取二进制文件强转换byte型获取真实编码后,不能使用readByte !=  
      113.      * -1 来判断是否到文件尾 
      114.      */  
      115.     public void testGetBytecodeByConvernt() {  
      116.         try {  
      117.             FileInputStream fi = new FileInputStream("e:/tmp/tmp");  
      118.             //读取的一个字节内容,强制转byte型,得到真实的编码  
      119.             byte readByte = (byte) fi.read();  
      120.             //这里我们不能使用如下方式来判断是否读流结束,因为编码内容本身就是-1,所以不会输出任何内容  
      121.             while (readByte != -1) {  
      122.                 System.out.println((byte) readByte);  
      123.                 readByte = (byte) fi.read();  
      124.             }  
      125.             fi.close();  
      126.         } catch (FileNotFoundException e) {  
      127.             e.printStackTrace();  
      128.         } catch (IOException e) {  
      129.             e.printStackTrace();  
      130.         }  
      131.     }  
  • 相关阅读:
    TLPI读书笔记第15章-文件属性2
    TLPI读书笔记第15章-文件属性1
    Java异常及错误
    10055
    4月。
    JavaScript三种方法获取地址栏参数的方法
    页面预加载loading动画,再载入内容
    什么是可串行化MVCC
    简化版扫雷详细解
    论unity中UI工具与GUI函数
  • 原文地址:https://www.cnblogs.com/gtaxmjld/p/4224721.html
Copyright © 2011-2022 走看看