Java IO之字节流

时间:2022-08-10 17:09:18

Java IO之字节流

一、Java字节流简介:

  在Java中,字节流一般适用于处理字节数据(诸如图片、视频),字符流适用于处理字符数据(诸如文本文件),但二者并没有严格的功能划分,因为有转换流的存在,使得对于数据的处理变得更加灵活。
  InputStream和OutputStream分别是字节输入流与字节输出流的抽象基类,它们的子类都是字节流,主要用在按字节来处理二进制数据

  InputStream抽象了应用程序读取数据的方式,OutputStream抽象了应用程序写出数据的方式

  FileInputStream--->具体实现了在文件上读取数据,FileOutputStream 实现了向文件中写出byte数据的方法

  DataOutputStream和DataInputStream是对"流"功能的扩展,可以更加方面的读取int,long,字符等类型数据

  BufferedInputStream和BufferedOutputStream,这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能

  性能比较:从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:,其中:

    FileOutputStream--->write()方法相当于一滴一滴地把水“转移”过去

    DataOutputStream-->writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去

    BufferedOutputStream--->write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了

  文件读取:EOF = End   读到-1就读到结尾

  本篇从字节流开始。主要包含以下内容:

  • InputStream/OutPutStream - - -字节流基类
  • FileInputStream/FileOutputStream - - - - -处理文件类型
  • ByteArrayInputStream/ByteArrayOutputStream - - - -字节数组类型
  • DataInputStream/DataOutputStream - - - -装饰类
  • BufferedInputStream/BufferedOutputStream - - - -缓冲流

  常用字节流继承结构图:

Java IO之字节流

常用方法说明:

输入流基本方法

int  b = in.read();读取一个字节无符号填充到int低八位.-1是 EOF

in.read(byte[] buf)

in.read(byte[] buf,int start,int size)
输出流基本方法

out.write(int b)  写出一个byte到流,b的低8位

out.write(byte[] buf)将buf字节数组都写入到流

out.write(byte[] buf,int start,int size)

二、实例分析:

这里我们就基于字节流写个工具类分析分析吧

Java IO之字节流Java IO之字节流
 1 package me.io;  2 
 3 import java.io.BufferedInputStream;  4 import java.io.BufferedOutputStream;  5 import java.io.File;  6 import java.io.FileInputStream;  7 import java.io.FileOutputStream;  8 import java.io.IOException;  9 
 10 public class IOUtils {  11 
 12     /**
 13  * 读取指定文件内容,按照16进制输出到控制台 并且每输出10个byte换行  14  *  15  * @param fileName  16  * @throws IOException  17      */
 18     public static void printHex(String fileName) throws IOException {  19     // 把文件作为字节流进行读操作
 20     FileInputStream fis = new FileInputStream(fileName);  21     int b = 0;  22     int i = 1;  23     while ((b = fis.read()) != -1) {  24         if (b <= 0xf) {  25         // 单位数前面补0
 26         System.out.print('0');  27  }  28         System.out.print(Integer.toHexString(b) + "  ");  29         if (i++ % 10 == 0) {  30  System.out.println();  31  }  32  }  33  fis.close();  34  }  35 
 36     /**
 37  * 读取文件放入到字节数组中,再遍历打印到控制台  38  *  39  * @param fileName  40  * @throws IOException  41      */
 42     public static void printHexByByteArray(String fileName) throws IOException {  43     FileInputStream fis = new FileInputStream(fileName);  44     byte[] buf = new byte[20 * 1024];  45 
 46     /**
 47  * 从fis中批量读取字节,放入到buf这个字节数组中 从第零个位置开始放,最多放buf.length个字节 返回的是读到的字节个数  48  * 一次性读完,说明字节数组足够大  49      */
 50 
 51     /*
 52  int bytes = fis.read(buf, 0, buf.length);  53  int j = 1;  54  for (int i = 0; i < bytes; i++) {  55  if (buf[i] <= 0xf && buf[i] >= 0x0) {  56  System.out.print('0');  57  }  58  System.out.print(Integer.toHexString(buf[i]) + " ");  59  if (j++ % 10 == 0) {  60  System.out.println();  61  }  62  }*/
 63 
 64     int j = 1;  65     int bytes = 0;  66     while ((bytes = fis.read(buf, 0, buf.length)) != -1) {  67         for (int i = 0; i < bytes; i++) {  68         System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");  69         if (j++ % 10 == 0)  70  System.out.println();  71  }  72  }  73  fis.close();  74  }  75 
 76     /**
 77  * 文件拷贝,字节批量读取  78  *  79  * @param srcFile  80  * @param destFile  81  * @throws IOException  82      */
 83     public static void copyFile(File srcFile, File destFile) throws IOException {  84     if (!srcFile.exists())  85         throw new IllegalArgumentException("文件" + srcFile + "不存在!");  86     if (!srcFile.isFile())  87         throw new IllegalArgumentException(srcFile + "不是文件!");  88     FileInputStream fis = new FileInputStream(srcFile);  89     FileOutputStream fos = new FileOutputStream(destFile);  90     byte[] buf = new byte[8 * 1024];  91     int b = 0;  92     while ((b = fis.read(buf, 0, buf.length)) != -1) {  93         fos.write(buf, 0, b);  94         fos.flush();// 最好加上
 95  }  96  fis.close();  97  fos.close();  98  }  99 
100     /**
101  * 使用带缓冲区的字节流进行文件拷贝 102  * 103  * @param srcFile 104  * @param destFile 105  * @throws IOException 106      */
107     public static void copyFileByBuffer(File srcFile, File destFile) throws IOException { 108     if (!srcFile.exists()) 109         throw new IllegalArgumentException("文件" + srcFile + "不存在!"); 110     if (!srcFile.isFile()) 111         throw new IllegalArgumentException(srcFile + "不是文件!"); 112 
113     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); 114     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); 115     int c = 0; 116     while ((c = bis.read()) != -1) { 117  bos.write(c); 118         bos.flush();// 刷新缓冲区
119  } 120  bis.close(); 121  bos.close(); 122  } 123 
124     /**
125  * 单字节不带缓冲区拷贝文件 126  * 127  * @param srcFile 128  * @param destFile 129  * @throws IOException 130      */
131     public static void copyFileByByte(File srcFile, File destFile) throws IOException { 132     if (!srcFile.exists()) 133         throw new IllegalArgumentException("文件" + srcFile + "不存在!"); 134     if (!srcFile.isFile()) 135         throw new IllegalArgumentException(srcFile + "不是文件!"); 136     FileInputStream fis = new FileInputStream(srcFile); 137     FileOutputStream fos = new FileOutputStream(destFile); 138     int c = 0; 139     while ((c = fis.read()) != -1) { 140  fos.write(c); 141         fos.flush();// 刷新缓冲区
142  } 143  fis.close(); 144  fos.close(); 145  } 146 
147     /**
148  * 带缓冲区批量拷贝文件 149  * 150  * @param srcFile 151  * @param destFile 152  * @throws IOException 153      */
154     public static void cloneFile(File srcFile, File destFile) throws IOException { 155     if (!srcFile.exists()) 156         throw new IllegalArgumentException("文件" + srcFile + "不存在!"); 157     if (!srcFile.isFile()) 158         throw new IllegalArgumentException(srcFile + "不是文件!"); 159     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile)); 160     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); 161     byte[] buf = new byte[8 * 1024]; 162     int bytes = 0; 163     while ((bytes = bis.read(buf, 0, buf.length)) != -1) { 164         bos.write(buf, 0, bytes); 165  bos.flush(); 166  } 167  bis.close(); 168  bos.close(); 169  } 170 }
IOUtils.java
Java IO之字节流Java IO之字节流
 1 package me.io;  2 
 3 import java.io.FileOutputStream;  4 import java.io.IOException;  5 
 6 public class FileOutDemo {  7 
 8     public static void main(String[] args) throws IOException {  9     //若果文件不存在,则直接创建,如果文件存在,则删除后创建,如果要追加内容,则应该传入参数true
10     @SuppressWarnings("resource") 11     FileOutputStream fos = new FileOutputStream("demo/out.dat"); 12     
13     fos.write('A');//写入A的低八位
14     fos.write('B'); 15     
16     //写一个int,要写四次
17     int i = 0x7fffffff; 18     fos.write(i >>> 24); 19     fos.write(i >>> 16); 20     fos.write(i >>> 8); 21  fos.write(i); 22     IOUtils.printHex("demo/out.dat"); 23  } 24 }
FileOutputStream
Java IO之字节流Java IO之字节流
 1 package me.io;  2 
 3 import java.io.DataInputStream;  4 import java.io.FileInputStream;  5 import java.io.IOException;  6 
 7 public class DisDemo {  8 
 9     public static void main(String[] args) throws IOException { 10     String file = "demo/dos.dat"; 11     DataInputStream dis = new DataInputStream(new FileInputStream(file)); 12  System.out.println(dis.readInt()); 13  System.out.println(dis.readInt()); 14  System.out.println(dis.readDouble()); 15  System.out.println(dis.readLong()); 16  System.out.println(dis.readUTF()); 17  System.out.println(dis.readChar()); 18  } 19 }
DataInputStream
Java IO之字节流Java IO之字节流
 1 package me.io;  2 
 3 import java.io.DataOutputStream;  4 import java.io.FileOutputStream;  5 import java.io.IOException;  6 
 7 /**
 8  * DataOutputStream测试类  9  * @author Administrator 10  * 11  */
12 public class DosDemo { 13 
14     public static void main(String[] args) throws IOException { 15     String file = "demo/dos.dat"; 16     DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)); 17     dos.writeInt(10); 18     dos.writeInt(-10); 19     dos.writeDouble(10.5); 20     dos.writeLong(10l); 21     
22     //采用UTF-8编码写出:
23     dos.writeUTF("中国");//三个字节 24     //采用UTF-16be编码写出
25     dos.writeChars("中国");//两个字节
26  dos.close(); 27     IOUtils.printHex("demo/dos.dat"); 28  } 29 }
DataOutputStream
Java IO之字节流Java IO之字节流
 1 package me.io;  2 
 3 import java.io.File;  4 import java.io.IOException;  5 
 6 public class IOUtilsMain {  7 
 8     public static void main(String[] args) throws IOException {  9     // IOUtils.printHex("src/me/io/IOUtils.java"); 10     // IOUtils.printHexByByteArray("src/me/io/IOUtils.java");
11     long start = System.currentTimeMillis(); 12     //IOUtils.copyFile(new File("demo/1.mp3"), new File("demo/4.mp3"));//58 13     //IOUtils.copyFileByBuffer(new File("demo/1.mp3"), new File("demo/2.mp3"));//26631毫秒 14     //IOUtils.copyFileByByte(new File("demo/1.mp3"), new File("demo/3.mp3"));//39722
15     IOUtils.cloneFile(new File("demo/1.mp3"), new File("demo/5.mp3"));//77
16     long end = System.currentTimeMillis(); 17     System.out.println(end - start);//文件大小为3.2m
18  } 19 }
Main方法

这里从main方法打印结果可以看出:我们在拷贝文件时,建议用字节批量读取,相对较快一点