字节流&&字符流

如果要进行输入输出操作一般都会按照如下的步骤进行:

           ---通过File类定义了一个要操作文件的路径;

          ---通过字节流或字符流的子类对象为父类对象实例化;

          ---进行数据的读(输入),写(输出)操作;

         ---数据量属于资源操作,资源操作必须关闭;

对于java.io包而言它定义了两类流:

          ---字节流(JDK1.0):InputStream,OutputStream;

          ---字符流(JDK1.1)Reader,Writer

字节输出流:OutputStream

该类的定义:public abstract class OutputStream

extends Object

implements Closeable, Flushable

首先发现该类实现了两个接口:Closeable, Flushable。这两个接口定义如下:

Closeable接口(JDK1.5):public interface Closeable  //在JDK1.7之后引入了非常神奇的自动关闭机制,所以让Closeable多继承了一个AutoCloseable

public interface Closeable extends AutoCloseable{

          public void close() throws IOException;

}

 

Flushable接口(JDK1.5):void flush() throws IOException  

 

在OutputStream类里面一共提供有三个输出的方法:

            ---输出单个字节:public abstract void write(int b) throws IOException

            ---输出全部字节数组:public void write(byte[] b) throws IOException

            ---输出部分字节数组:public void write(byte[] b, int off, int len) throws IOException

OutputStream本身属于抽象类,如果想要为抽象类进行对象的实例化操作,那么一定要使用子类进行操作,于是进行的是文件操作所可以使用FileOutpuStream子类。在这个子类里定义有如下的构造方法:

       ---创建或覆盖已有文件:public FileOutputStream(File file)throws FileNotFoundException

       ---文件内容追加:public FileOutputStream(File file,boolean append)throws FileNotFoundException

范例:文件内容的输出:

       

package test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Demo01 {
	public static void main(String[] args) throws Exception {//此处直接抛出
	      File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输出的文件路径
	      //此时由于目录不存在,所以文件不能输出,那么应该首先创建目录
	      if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();//创建目录
		}
	      //应该使用OutputStream和其子类进行对象的实例化,此时目录存在,文件还不存在
	      OutputStream outputStream=new FileOutputStream(file);
	      //要进行文件内容的输出
	      String string="好好学习,天天向上";
	      byte data[]=string.getBytes();//将字符串变为字节数组
	      outputStream.write(data); //将内容输出
	      outputStream.close();//资源操作的最后一定要关闭
	      
	}
}

以上是将整个字节数组的内容进行输出,并且发现,如果此时要输出的文件不存在,那么会自动进行创建。可是对于输出操作在整个OutputStream类里面一共定义有三个操作方法。

范例1:采用单个字节的方式输出。

for(int x=0;x<data.length;x++){
       output.write(data[x]);
}

范例2:输出部分字节数组内容

output.write(data,6,6);

但是每次都是覆盖不是很好,希望可以实现内容的追加,那么只需要更换FileOutputStream类的构造方法即可。

	      //应该使用OutputStream和其子类进行对象的实例化,此时目录存在,文件还不存在
	      OutputStream outputStream=new FileOutputStream(file,true);
	      //要进行文件内容的输出
	      String string="好好学习,天天向上 \r\n";

字节输入流:InputStream

如果程序需要进行数据的读取操作,可以利用InputStream类实现功能,此类定义如下:

public abstract class InputStream extends Object implements Closeable

虽然也定义了Closeable接口,但是与OutputStream类一样,不用去考虑此接口的存在。在InputStream里面也定义有数据读取的方法。

         ---读取单个字节:public abstract int read() throws IOException

         ---将读取到的数据保存在字节数组里面:public int read(byte[] b)throws IOException

         ---将读取到的数据保存在部分字节数组里:public int read(byte[] b,int off,int len)throws IOException

InputStream类是抽象类,因此如果想要为抽象类进行实例化操作,那就使用其子类FileInputStream类进行实例化操作。该子类的构造方法:

public FileInputStream(String name) throws FileNotFoundException

范例:向数组里读取数据

package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo01 {
	public static void main(String[] args) throws Exception {//此处直接抛出
	      File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
	      //需要判断文件存在后才可以进行读取
	      if (file.exists()) {
			//使用InputStream类进行读取
	    	  InputStream inputStream=new FileInputStream(file);
	    	  byte data[]=new byte[1024];//准备输出一个1024的数组
	    	  int len=inputStream.read(data);//将字节内容保存到字节数组之中
	    	  inputStream.close();
	    	  System.out.println("["+new String(data,0,len)+"]");
		}
	}
}

范例:单个字节数据读取

       ---由于一个文件存在很多的字节数据,所以如果要读取肯定采用循环的方式进行读取,由于不确定循环次数,所以使用while()循环完成。

package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo01 {
	public static void main(String[] args) throws Exception {//此处直接抛出
	      File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
	      //需要判断文件存在后才可以进行读取
	      if (file.exists()) {
			//使用InputStream类进行读取
	    	  InputStream inputStream=new FileInputStream(file);
	    	  byte data[]=new byte[1024];//准备输出一个1024的数组
	    	  int foot=0;//表示字节数组的操作指标
	    	  int temp=0;//表示每次读取的字节数据
	    	  while ((temp=inputStream.read())!=-1) {//将read()方法读取的字节内容给了temp变量,并且判断读取的内容是否为-1
				data[foot++]=(byte)temp;
			}
	    	  inputStream.close();
	    	  System.out.println("["+new String(data,0,foot)+"]");
		}
	}
}

字符输出流:Writer

writer类是在JDK1.1之后增加的,其类的定义如下:

public abstract class Writer extends Object implements Appendable, Closeable, Flushable

这个类除了实现 Closeable, Flushable接口外,又多实现了一个接口Appendable,这个接口定义如下:

public interface Appendable
public interface Appendable{
Appendable	append(char c) 
         // 向此 Appendable 添加指定字符。
 Appendable	append(CharSequence csq) 
        //  向此 Appendable 添加指定的字符序列。
 Appendable	append(CharSequence csq, int start, int end) 
       //   向此 Appendable 添加指定字符序列的子序列。
}

 

在Appendable中定义了追加的操作,而且追加的数据都是字符或者字符串。

在Writer类里面定义有以下的输出方法(部分):

           ---输出全部字符数组:public void write(char[] cbuf) throws IOException

          ---输出字符串:public void write(String str) throws IOException

Writer是一个抽象类,如果想要为这个类的对象实例化,应该使用FileWriter子类。

范例:使用Writer类进行内容输出

package test;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
public class Demo01 {
	public static void main(String[] args) throws Exception {//此处直接抛出
	      File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
	      //需要判断文件存在后才可以进行读取
	      if (!file.getParentFile().exists()) {
	    	  file.getParentFile().mkdirs();
		}
	      //实例化Writer类的对象
	      Writer out=new FileWriter(file);
	      //进行内容输出
	      String string="千万不要被节后综合征所打败";
	      out.write(string);//输出字符串数据
	      out.close();//关闭输出流
	}
}

可以发现Writer作为字符输出流,可以直接进行字符串的输出,这一点就比OutputStream强了

字符输入流:Reader

Reader是进行字符数据读取的输入流,其本身也是一个抽象类:

public abstract class Reader extends Object implements Readable, Closeable

在Reader类里面也提供有一系列的read()方法:

                ---读取内容到字符数组:public int read(char[] cbuf) throws IOException

               返回值:表示读取的数据长度,如果以及读取到结尾了返回-1.

为Reader类实例化的可以使用FileReader子类完成。

范例:使用Reader

package test;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
public class Demo01 {
	public static void main(String[] args) throws Exception {//此处直接抛出
	      File file= new File("e:"+File.separator+"demo"+File.separator+"dome.txt");//设置要输入的文件路径
	      //需要判断文件存在后才可以进行读取
	      if (file.exists()) {
	    	 //为Reader类对象实例化
	    	  Reader in=new FileReader(file);
	    	  //进行数据读取
	    	  char data []=new char [1024];
	    	  int len=in.read(data);
	    	  //关闭输入流
	    	  in.close();
	    	  System.out.println(new String(data,0,len));
		}
	}
}

与字节输入流相比结构几乎是一样的,只是数据类型由byte改为char而已。

字节流和字符流的区别?

字节流和字符流最大的区别是,字节流直接与终端进行交互,而字符流需要将数据经过缓冲区处理后才可以输出。

在使用OutputStream输出数据的时候即使最后没有没有关闭输出,那么内容也可以正常输出。但如果使用的的是字符输出流,如果不关闭,那么就表示在缓冲区之中处理的内容不会被强制性地清空,所以就不会输出数据。如果某种情况下不能关闭字符输出流,可以使用flush方法强制清空缓冲区。

范例:强制清空字符流缓冲区。out.flush();

在开发之中,对于字节数据地处理是比较多的,例如:图片,音乐,电影。。。。。对于字符流最大的好处是它可以进行中文地有效处理。在以后地开发之中,如果要处理中文的时候请优先考虑字符流,如果没有中文问题,建议使用字节流。

                                                                                                                                                      2018-08-12    20.54

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值