字节流与字符流(一)

一标题:字节输出流:OutputStream

知识点:

      File类虽然可以操作文件,但是不支持操作文件内容,如果要对内容进行操作只有两种方式:字符流和字节流。

具体内容:

     如果要进行输入,输出操作一般都会按照如下的步骤进行(以文件操作为例):

  • 通过File类定义一个要操作文件的路径(不是文件就没有这一步);
  • 通过字节流或则字符流的子类对象为父类对象实例化;
  • 进行数据的读(写入),写(输出)操作;
  • 数据流属于资源操作,资源操作必须关闭;

JAVA.IO包定义了两类流:

  • 字节流(JDK1.0):InputStream、OutputStream;
  • 字符流(JDK1.1):Reader、Writer;

字节输出流OutputStream:

    OutputStream类是一个专门进行字节流数据输出的一个类,这个定义如下:

  • public abstract class OutputStream
    extends Object
    implements Closeable, Flushable

   OutputStream类实现了两个接口:Closeable,Flushable

        

Closeable接口:(JDK1.5)Flushable接口:(JDK1.5)
  • public interface Closeable
    extends AutoCloseable{
      public void close() 
        throws IOException
    }
  • public interface Flushable{  
      public void flush()
        throws IOException
    }
  • public interface AutoCloseable{  
      public void close()
        throws 异常
    }
  • JDK1.7引入
 

 

OutputStream类在JDK1.0的时候提供,且这个类原本就定义了close()与flusah()方法,故以上两个接口就可以忽略不记了。

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子类,FileOutputStream类:

          public FileOutputStream(String name, boolean append) throws FileNotFoundException

  1. 创建或覆盖已有文件:public FileOutputStream(File file) throws FileNotFoundException
  2. 文件内容追加:public FileOutputStream(File file, boolean append) throws FileNotFoundException

代码一:将整个字节数组的内容进行了输出。

package 字节流与字符流;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class TestD {

	public static void main(String[] args) throws Exception {  //此处抛出
		//1.定义要输出文件的路径
		File file=new File("D:"+File.separator+"Demo"+File.separator+"my.txt");
		//此时由于目录不存在,所以文件不能够输出,那么应该先创建目录
		if(!file.getParentFile().exists()){//文件能目录不存在
			file.getParentFile().mkdirs();   //创建目录	
		}
		//2.应该使用OutputStream和其子类进行对象实例化,此时目录存在,文件不存在
		OutputStream output=new FileOutputStream(file);
		//3.要进行文件内容的输出
		String str="好好学习,天天向上!";
		byte data []=str.getBytes();//将字符串变为字节数组
		output.write(data);
		//4.资源操作的最后一定要进行关闭
		output.close();
	}

}

     以上代码是将整个字节数组进行输出,并且在输出之前,如果输出的文件不存在还可以创建之后,再输出。对于输出操作再整个OutputsStream类里面一共定义了三个方法。

代码二:采用单个字节的方式输出。

for(int x=0;x<data.length;x++){
    output.write(data[x]);   //将内容输出
   }

代码三:输出部分字节数组内容。注:一个中国字等于两个字符,当长度为基数的时候就差一个字符的空间就会显示问号。

	output.write(data,6,6);

      但是以上三段代码由于FileOutputStream构造方法的原因,每一次写入都会覆盖,因此如果需要追加内容就只需要更换FileOutputStream构造方法。只要程序输出内容,都可以利用OutputStream类完成。

 

二标题:字节输入流:InputStream

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

  • public abstract class InputStream
    extends Object
    implements Closeable

读取方法:

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

            —返回值:返回读取的单个字节,如果已经读完就返回-1.

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

            —返回值:返回数据读取的长度,如果读取到结尾了,返回-1;

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

            —返回值:读取的部分数据的长度,如果已经读取到结尾了,返回-1.

      由于InputStream是一个抽象类,所以要利用它的子类FileInputStream子类进行文件读取。

              构造方法:public FileInputStream(File file) throws FileNotFoundException

范例: 向数组里面读取数据

package 字节流与字符流;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class TestD {

	public static void main(String[] args) throws Exception {  //此处抛出
		//1.定义要输出文件的路径
		File file=new File("D:"+File.separator+"Demo"+File.separator+"my.txt");
		//1.需要判断文件是否存在后才可以进行读取
		if(file.exists()){  //文件存在
			//2.使用InputStream进行读取
			InputStream input=new FileInputStream(file);
			//3.进行数据读取
			byte data [] = new byte [1024];   //准备出一个1024数组
			int temp=input.read(data);       //将内容保存到字节数组
			//4.关闭输入流
			input.close();
			System.out.println("【"+new String(data,0,temp)+"】");
		}
	
	}

}

范例:单个字节读取数据

           因为一个文件有很多的数据,故只能利用循环进行读取。另外没有确定循环次数,因为只能通过while循环。

实现一(了解):do...while

//3.进行数据读取
byte data [] = new byte [1024];   //准备出一个1024数组
int foot=0;
int temp=0;
do{
	temp=input.read(); //读取一个字节
	if(temp!=-1){      //现在是真实的内容
	data[foot++]=(byte)temp;    //保存读取的字节到数组中
    }
  }while(temp!=-1);   //如果现在读取的temp的字节数据不是-1.表示还有内容
//4.关闭输入流
input.close();

实现二(重点):whie 

//3.进行数据读取
			byte data [] = new byte [1024];   //准备出一个1024数组
			int foot=0;
			int temp=0;
			//第一部分:temp=input.read(),表示将read()读取的字节内容给了temp变量
			//第二部分:temp=input.read()!=-1,判断读取出来的temp内容是否是-1
			while((temp=input.read())!=-1){
				data[foot++]=(byte) temp;     //有内容进行保存
			}
			//4.关闭输入流
			input.close();

  此类读取方式是开发中使用最多的情况。 

三、字符输出流:Writer

      Writer类是在JDK1.1中增加的,其类的定义如下:

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

这个类出了实现Closeable和Flushable接口外,又多实现了appendable,其定义如下:

  • public interface Appendable{
    Appendable append(char c)
               throws IOException
  • Appendable append(CharSequence csq)
           throws IOException
    
    Appendable append(CharSequence csq,
                      int start,
                      int end)
               throws IOException

在Appendable接口里面定义了追加的操作,而且追加的数据都是字符串和者字符。

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

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

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

Writer由于是一个抽象类,所以在实例化的时候应该用其子类FileWriter子类;

代码:

package 字节流与字符流;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class TestD {

	public static void main(String[] args) throws Exception {  //此处抛出
		//1.定义要输出文件的路径
		File file=new File("D:"+File.separator+"Demo"+File.separator+"my.txt");
		if(file.getParentFile().exists()){
			file.getParentFile().mkdirs();
		}
		//2.实例化Writer类对象
			Writer out=new FileWriter(file);
		//3.进行内容输出
			String str="千万不要被节后综合征打败,你们所有人都已经开始挑战我了!";
			out.write(str); //输出字符串
		//4.关闭输出流
			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 字节流与字符流;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;

public class TestD {

	public static void main(String[] args) throws Exception {  //此处抛出
		//1.定义要输出文件的路径
		File file=new File("D:"+File.separator+"Demo"+File.separator+"my.txt");
	    if(file.exists()){
	    	//2.为Reader类对象实例化
	    	Reader in=new FileReader(file);
	    	//3.读取数据
	    	char data []=new char [1024];
	    	int len=in.read(data);
	    	//4.关闭输入流
	    	in.close();
	    	System.out.println(new String(data,0,len));
	    }
	}
	}

与字节输入流相比结构几乎一样,但是数据类型由byte更换为了 char而已。

五、字节流与字符流的区别?

       区别:字节流直接与终端进行数据交互,而字符流需要将数据经过缓冲区进行处理后才可以输出。在使用OutputStream输出数据的时候最后即时没有关闭流,那么内容也可以正常输出,但是如果使用的是字符输出流,如果不关闭那么就表示在缓冲区的内容不会被强制性的清空,所以就不会输出数据.如果有特殊情况不能够关闭字符输出流,可以使用flush()方法强制清空缓冲区。

代码:强制清空字符流缓冲区

package 字节流与字符流;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;

public class TestD {

	public static void main(String[] args) throws Exception {  //此处抛出
		//1.定义要输出文件的路径
		File file=new File("D:"+File.separator+"Demo"+File.separator+"my.txt");
	   if(!file.getParentFile().exists()){
		   file.getParentFile().mkdirs();
	   }
	   Writer out=new FileWriter(file);
	   String str="你好!";
	       out.write(str);//输出字符串数据
	       out.flush();//强制清空缓冲区
	}
	}

 在开发之中,对于字节数据处理比较多,比如:图片,音乐,电影、文字。而对于字符流最大的好处是可以对中文进行有效处理。

总结:

     1.字节流的输出以及输入操作的代码必须熟练掌握。

         即:OutputStream类与InputStream类中的write()和read()方法必须掌握清楚;

      2.中文处理的时候强烈建议使用字符流。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值