java IO之字节流与字符流

 在整个IO包中,流的操作就分为两种:

字节流和字符流

字节流:InputStreamOutputStream

字符流:ReaderWriter,一个字符=两个字节

以上的四个类都是抽象类,抽象类的特点就是根据实例化它子类的不同完成的功能也不同,如果是文件操作则使用FileXxx.

字符流在操作的时候使用到了缓存,字节流是直接实现底层的IO操作。

 

IO操作的基本步骤

1.         java中使用IO操作必须按照以下的步骤完成:

2.         使用File找到一个文件

3.         使用字节流或字符流的子类为OutputStreamInputStreamWriterReader进行实例化操    作

4.         进行读或写的操作

5.         关闭:Close(),在流的操作宏最终必须进行关闭

字节流输出流:OutputStream

java.io包中OutputStream是字节输出流的最大父类。

此类是一个抽象类,所以使用时需要依靠子类进行实例化操作。如果此时要完成文件的输出操作,则使用FileOutputStream OutputStream进行实例化操作。

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileOutputStream; 
  3. import java.io.OutputStream; 
  4. public class OutputStreamDemo { 
  5.     public static void main(String[] args) throws Exception { 
  6.         File file = new File("D:" + File.separator + "OutWrite.txt"); 
  7.         OutputStream outputStream = null;//声明字节输出流 
  8.         outputStream = new FileOutputStream(file);//通过子类实例化 
  9.         String string = "hello World FILE!";//要输出的信息 
  10.         byte[] b = string.getBytes();//将String变为Byte数组 
  11.         outputStream.write(b);//写入数据 
  12.         outputStream.close();//关闭 
  13.     } 

以上的操作是将全部的字节数组内容输出,当然,也可以通过循环一个一个输出 

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileOutputStream; 
  3. import java.io.OutputStream; 
  4.  
  5. public class OutputStreamDemo2 { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt"); 
  8.         OutputStream outputStream = null;//声明字节输出流 
  9.         outputStream = new FileOutputStream(file);//通过子类实例化 
  10.         String string = "hello World FILE!";//要输出的信息 
  11.         byte[] b = string.getBytes();//将String变为Byte数组 
  12.     for (int i = 0; i < b.length; i++) { 
  13.         outputStream.write(b[i]); 
  14.     } 
  15.         outputStream.close();//关闭 
  16.     } 

但是,以上执行的时候可以发现也会存在一些问题,每一次执行完之后,所有的内容将会被新的内容替换。如果希望追加内容,则需要观察FileOutputStream类的构造方法:

public FileOutputStream(File file, boolean append) throws FileNotFoundException

如果将append的内容设置为true.

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileOutputStream; 
  3. import java.io.OutputStream; 
  4.  
  5. public class OutputStreamDemo2 { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt"); 
  8.         OutputStream outputStream = null;//声明字节输出流 
  9.         outputStream = new FileOutputStream(file,true);//通过子类实例化 
  10.         String string = "hello World FILE!\r\n";//要输出的信息,\r\n表示换行 
  11.         byte[] b = string.getBytes();//将String变为Byte数组 
  12.     for (int i = 0; i < b.length; i++) { 
  13.         outputStream.write(b[i]); 
  14.     } 
  15.         outputStream.close();//关闭 
  16.     } 

字节输入流:InputStream

使用InputStream可以读取输入流的内容

此类也属于一个抽象类,那么如果想要使用的话,则肯定还是依靠其子类,如果现在是文件操作则使用的是FileInputStream.

FileInputStream的构造方法:

public FileInputStream(File file) throws FileNotFoundException

实例化之后就可以通过如下的方法取得数据

将内容读到字节数组之中:public int read(byte[] b) throws IOException

每次读一个数据:public int read()throws IOException

例如读取文件内容 

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileInputStream; 
  3. import java.io.InputStream; 
  4.  
  5. public class InputStreamDemo { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt");// 要操作的文件 
  8.         InputStream inputStream = null;// 字节输入流 
  9.         inputStream = new FileInputStream(file);// 通过子类进行实例化 
  10.         byte[] b = new byte[1024];// 开辟空间接收读取的内容 
  11.         int len = inputStream.read(b);// 将内容读入到byte数组中 
  12.         System.out.println(new String(b, 0, len));// 输出长度为len的字符串内容 
  13.         inputStream.close();// 关闭 
  14.     } 

以上是一种比较常见的读取形式,但是以上的代码有一个缺点,会受到开辟空间的限制,如果现在想动态的开辟数组的空间,则可以根据文件的大小来决定,采用read()方法一个个的读取数据

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileInputStream; 
  3. import java.io.InputStream; 
  4.  
  5. public class InputStreamDemo1 { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt");// 要操作的文件 
  8.         InputStream inputStream = null;// 字节输入流 
  9.         inputStream = new FileInputStream(file);// 通过子类进行实例化 
  10.         byte[] b = new byte[(int) file.length()];// 开辟空间接收读取的内容 
  11.         for (int i = 0; i < b.length; i++) { 
  12.             b[i] = (byte) inputStream.read(); 
  13.         } 
  14.         System.out.println(new String(b));// 输出内容 
  15.         inputStream.close();// 关闭 
  16.     } 

字符输出流:Writer

 Writer类是在IO包中操作字符的最大父类,主要功能是完成字符流的输出。

OutputStream一样,都属于抽象类,如果要进行文件中的保存,则使用FileWriter

写入操作:public void write(String str) throws IOException。不用再转换。 

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileWriter; 
  3. import java.io.Writer; 
  4. public class WriterDemo { 
  5.     public static void main(String[] args) throws Exception { 
  6.         File file = new File("D:" + File.separator + "OutWrite.txt"); 
  7.         Writer writer = null;//声明字节输出流 
  8.         writer= new FileWriter(file);//通过子类实例化 
  9.         String string = "hello World FILE!";//要输出的信息 
  10.         writer.write(string);//写入字符串 
  11.         writer.close();//关闭 
  12.     } 

程序也可以进行内容的追加:public FileWriter(File file, boolean append) throws IOException 

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileWriter; 
  3. import java.io.Writer; 
  4. public class WriterDemo { 
  5.     public static void main(String[] args) throws Exception { 
  6.         File file = new File("D:" + File.separator + "OutWrite.txt"); 
  7.         Writer writer = null;//声明字节输出流 
  8.         writer= new FileWriter(file,true);//通过子类实例化 
  9.         String string = "hello World FILE!\r\n";//要输出的信息 
  10.         writer.write(string);//写入字符串 
  11.         writer.close();//关闭 
  12.     } 

字符输入流:Reader

字符输入流与字节输入流的不同地方:使用的是char数组。

是一个抽象类,要是现在进行文件的读取使用FileReader进行实例化。

读取方法:

  读取以组字符:public int read(char[] cbuf) throws IOException

读取一个个字符:public int read() throws IOException 

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileReader; 
  3. import java.io.Reader; 
  4.  
  5. public class ReaderDemo { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt");// 要操作的文件 
  8.         Reader reader = null;// 字符输入流 
  9.         reader = new FileReader(file);// 通过子类进行实例化 
  10.         char[] b = new char[1024];// 开辟空间接收读取的内容 
  11.         int len = reader.read(b);// 将内容读入到char数组中 
  12.         System.out.println(new String(b, 0, len));// 输出内容 
  13.         reader.close();// 关闭 
  14.     } 

以上完成了一个字符的输入流,那么当然也可以通过循环的方式,一个个的进行读取的操作。

   
   
   
   
  1. import java.io.File; 
  2. import java.io.FileReader; 
  3. import java.io.Reader; 
  4.  
  5. public class ReaderDemo1 { 
  6.     public static void main(String[] args) throws Exception { 
  7.         File file = new File("D:" + File.separator + "OutWrite.txt");// 要操作的文件 
  8.         Reader reader = null;// 字符输入流 
  9.         reader = new FileReader(file);// 通过子类进行实例化 
  10.         char[] b = new char[(int) file.length()];// 开辟空间接收读取的内容 
  11.         for (int i = 0; i < b.length; i++) { 
  12.             b[i] = (char) reader.read(); 
  13.         } 
  14.         System.out.println(new String(b));// 输出内容 
  15.         reader.close();// 关闭 
  16.     } 

字节流与字符流的区别

字节流在操作的时候是直接与文件本身关联,不适用缓冲区

字节à文件

字符流在操作的时候是通过缓冲区与文件操作

字符à缓冲à文件

综合比较来说,在传输或者在硬盘上保存的内容都是以字节的形式存在的,所以字节流的操作较多,但是在操作中文的时候字符流比较好用。