字节流与字符流
一.基本介绍
在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。其中包括:InputStream,OutputStream,Reader,Writer等
InputStream 和OutputStream,两个是为字节流设计的,主要用来处理字节或二进制对象,
Reader和 Writer.两个是为字符流(一个字符占两个字节)设计的,主要用来处理字符或字符串.
字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的 但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化 这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联 在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的
Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1,inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取。
简单来说:
字符流=字节流+解码器
字节流=字符流+编码器
字符流的产生是为了在处理文字数据更方便的操作。
注意:①字节流是直接与数据产生交互,而字符流在与数据交互之前要经过一个缓冲区 。
字节流直接对文件进行操作,flush方法为空。而字符流带有缓冲区,重写了flush方法。
OutputStream的直接子类有ByteArrayOutputStream, FileOutputStream, FilterOutputStream,ObjectOutputStream,OutputStream,PipedOutputStream,其中绝大部重写flush方法的子类调用的还是父类的空的flush方法,重点看FilterOutputStream的子类BufferedOutputStream重写的flush方法,调用了flushBuffer();这个方法。
②每次调用close方法都会自动调用flush方法,调用close后,不能 在进行写入,因为写入的流已经关闭。
2.字节流字符流简单用法
public class IoputStreamdemo {
public static void main(String []args) throws IOException
{
}
private static void method5(FileInputStream is) throws IOException {
byte [] buf=new byte[1024];
int len;
while((len=is.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
}
}
private static void method4(FileInputStream is) throws IOException {
int len;
while((len=is.read())!=-1)
{
System.out.println((char)len);
}
}
private static void method3() throws IOException {
FileWriter fw=new FileWriter("demo1.txt",true);
String str="woshishabi2";
String str2="dad2";
fw.write(str);
fw.write(str2);
fw.flush();
fw.close();
}
private static void method1() throws FileNotFoundException, IOException {
OutputStream os=new FileOutputStream("demo1.txt");
String str="woshishabi";
String str2="dad";
os.write(str.getBytes());
os.write(str2.getBytes());
}
}
二 流的转换
我们知道硬盘中的文件是字节数据,同样在硬盘中存储的txt文本文件也是按照字节进行存储的,如果我们想用字符流中的方式对字节数据进行操作。就可以使用InputStreamReader类,将文件中字节数据转化为字符数据。在对字符数据进行操作。
而如果我们手上的是字符数据,要输出到硬盘上,而硬盘接受的只能是字节数据。怎么办呢?就可以使用OutputStreamWriter类,将手中的字符数据编程字节数据,存储到硬盘上。
Example1:
将键盘输入的字符转化为大写并输出到控制台上
分析:键盘是一种输入流,是外部设备。 控制台也是一种外部设备,是输出流。他们两个都只认识字节流。
键盘输入的是字节数据,我们可以先把字节数据转化为字符数据(便于操作),操作完成后,我们把字符数据转化成字节数据输出到控制台上。
private static void method3() throws IOException
{
InputStream is=System.in;
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String str=null;
OutputStream out=System.out;
OutputStreamWriter osw=new OutputStreamWriter(out);
BufferedWriter bw=new BufferedWriter(osw);
while((str=br.readLine())!=null)
{
if(str.equals("over"))
break;
else
bw.write(str.toUpperCase());
bw.newLine();
bw.flush();
}
/*
* 从键盘读取到了字节,通过InputSteamReader转化字符打印在控制台上
* 而如果我们获取的是字符,控制台只接受字节,怎么把字符转化为字节打印到控制台上呢?
* 通过OutputStreamWriter把写入的内容由字符转为字节。
*/
}
Example2:常见转换
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class IOchangedemo2 {
public static void main(String []args) throws IOException
{
method2();
}
private static void method2() throws FileNotFoundException, IOException {
/*
目的将键盘中内容读取并输出到文件上
*/
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("demo.txt")));
BufferedReader br=new BufferedReader (new InputStreamReader(System.in));
String str=null;
while((str=br.readLine())!=null)
{
if(str.equals("over"))
break;
bw.write(str);
}
bw.close();
br.close();
}
private static void method1() throws FileNotFoundException, IOException {
/*
目的将文本文件中内容读取并输出到控制台上
*/
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
BufferedReader br=new BufferedReader (new InputStreamReader(new FileInputStream("demo.txt")));
String str=null;
while((str=br.readLine())!=null)
{
bw.write(str);
}
bw.close();
br.close();
}
}