先来点基础知识:

1字节=8bit(位)

Java中

但是utf-8下:

1字符 = 1字节

1字符 = 3字节(中文)

Unicode下:

字符 = 2字节

 

InputStream和FileInputStream区分:

InputStream是接口,不能实例化,FileInputStream是InputStream的实现类,用以读取字节流

 

FileReader和InputStreamReader

都是字符流,但是两者构造器不同:

new InputStreamReader(InputStream in)//将流作为参数
new FileReader(File或fileName)//将文件或文件路径及名称作为路径
 
//字节流
fis = new FileInputStream(new File(“d://aa.txt”));
n = fis.read(byte[])//fis还有内容返回读取的字节数,否则返回-1
 
//字符流
fileReader=new FileReader("d:\\aa.txt");
inputStreamReader = new InputStreamReader(System.in);
(n=fileReader.read(char[]))!=-1//fileReader还有内容返回读取的字符数,否则返回-1
 
//字符串流
BufferedReader br=new BufferedReader(fileReader);或
new BufferedReader(inputStreamReader)
(s=br.readLine())!=null//直接返回读取的字符串

从字节-->字符-->字符串流,本质就是读取的单位越来越大.其实本质上计算机能识别的只有0和1(位bit),但是bit根本不能存储小的信息单位,所以数据是以字节为单位存储的。

问题1:有了字节流为什么还需要字符流?

本质问题就是有了字节为什么还需要字符,参照上面 Ascii,Unicode和utf-8之间的区分与联系.

 

问题2:什么时候使用字节流、什么时候使用字符流?

字节流与字符流区别:

1)字节流在操作时不会用到缓冲区(内存),直接对文本本身进行操作;但字符在操作时使用了缓冲区,通过缓冲区在操作文件

2)在硬盘上所有文件都是以字节形式存在(图片,音频,视频),字符在内存中才会形成

针对第一点:如果一个程序频繁对资源做IO操作,使用字节流,效率会很低;如果使用字符流,把需要操作的数据暂时放到内存中,以后直接从内存读取,避免多次IO操作,提高效率;

针对第二点:真正存储和传输数据都是以字节为单位的,字符仅存在于内存,所以字节使用范围更广.

结论:

字节用来读取英文,图片,歌曲,视频还能内容比较适合

但是中文之类的应该使用字符流,可以提高效率


下面是简单的例子:


1读取文件内容到内存中并进行打印

指向固定文件—》文件转化为文件流—》将文件流读取到字节数组—》字节数组转化为String

 

package ioStream;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
 
//讲一个文件读入内存
 
public class FileIO2 {
 
public static void main(String[] args) {
// TODO Auto-generated method stub
File file=new File("d:\\aa.txt");
FileInputStream fis=null;
//因为file没有读和写的能力,所以使用inputStream流
try {
//将文件转化为流
fis=new FileInputStream(file);
//建立一个缓存,存储读入的内容
byte[]  bytes=new byte[1024];
int n=0;
//将fis流中的内容读入字节数组,
//用read方法,当有内容读入时,返回读取数据的内容,如果已经到达文件末尾则返回-1
while((n=fis.read(bytes))!=-1){
String str=new String(bytes, 0, n);
System.out.println(str);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭文件流
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 
}

 

 

字节流需求二:从键盘接收用户的输入,并写入到指定文件

/**
 * 
 */
package ioStream;
 
import java.io.*;
 
public class WriteToFile {
 
public static void main(String[] args) {
// TODO Auto-generated method stub
File file=new File("d:\\a.txt");
//字节输出流
FileOutputStream fos=null;
//从键盘接收输入的值
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try{
fos=new FileOutputStream(file);
System.out.println("please input:");
String s=br.readLine();
//定义字节数组
byte[]  bytes=new byte[1024];
//如何把string转化为字节数组
bytes=s.getBytes();
//注意,此时会直接写入,并且对原本的内容进行覆盖!
fos.write(bytes);
}catch(Exception  e){
e.printStackTrace();
}finally{
try {
fos.close();
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
 
}

 

字节流需求三:事项指定路径的文件拷贝到指定的路径

package ioStream;
 
import java.io.*;
 
public class JpgCopy {
 
public static void main(String[] args) {
 
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis=new FileInputStream("d:\\a.jpg");
fos=new FileOutputStream("d:\\b.jpg");
byte[]  bytes=new byte[1024];
int n=0;
while((n=fis.read(bytes))!=-1){
fos.write(bytes,0,n);
}
}catch(Exception  e){
e.printStackTrace();
}finally{
try {
fos.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
}
 
}