字符流:(文本)
走的是字节,但是要把字节临时存起来
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流:(图片,音乐)
InputStream OutputStream
想要操作图片流数据,这时就要用到字节流
例:
import java.io.*;
class FileStream
{
public static void main(String[] args)throws IOException
{
readFile_1();
readFile_2();
readFile_3();
}
public static void readFile_3()throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
//int num = fis.available();//计算字节数
byte[] buf = new byte[fis.available()];// 定义一个刚刚好的缓冲区,不用再循环
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
public static void readFile_2()throws IOException //读1024个字节打印,这种方式最适中
{
FileInputStream fis = new FileInputStream("fos.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf)) != -1)
{
System.out.println(new String(buf, 0, len)); //输出在命令提示符中
}
fis.close();
}
public static void readFile_1()throws IOException //读一个打印一个
{
FileInputStream fis = new FileInputStream("fos.txt");//建立一个读取字节流对象
int ch = 0;
while((ch=fis.read()) != -1)//循环判读是否为空
{
System.out.println((char)ch); 输出
}
fis.close();
}
public static void writeFile()throws IOException
{
FileOutputStream fos = new FileOutputStream("fos.txt");//建立一个写入字节流对象
fos.write("abcde".getBytes());//把字符串转成字节
fos.close();
}
}
复制一个图片
思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件,用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。
代码:
import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
FileOutputStream fos = null;
FileInputStream fis = null;
try
{
fos = new FileOutputStream("D:\\IMG_0523.JPG");//创建输出流文件对象
fis = new FileInputStream("E:\\IMG_0523.JPG");//创建读取流文件对象
byte[] bt = new byte[1024];
int num = 0;
while((num = fis.read(bt)) != -1)
{
fos.write(bt, 0, num);//写入流文件
}
}
catch(IOException e)
{
throw new RuntimeException("复制失败");
}
finally
{
try
{
if(fis != null)//判断是否为空
fis.close();
}
catch(IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(fos != null)
fos.close();
}
catch(IOException e)
{
throw new RuntimeException("输出关闭失败");
}
}
}
}
/*
演示mp3的复制,通过缓冲区
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class CopyMp3
{
public static void main(String[] args)throws IOException
{
long start = System.currentTimeMillis();//获取系统当前时间
copy();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");//计算复制耗时
}
//通过字节流的缓冲区完成复制
public static void copy()throws IOException
{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\Psy.mp3"));//创建读取文件缓冲区对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\PP.mp3"));//创建输出文件缓冲区对象
int num =0 ;
while((num=bis.read()) != -1)
{
bos.write(num); //不可以用readLine()和newLine()方法,这个是在文本文件时使用
}
bis.close();
bos.close();
}
}
字符流:
FileReader FileWriter
BufferedReader BufferedWriter
字节流:
FileInputStream FileOutputStream
BufferedInputStream BufferedOutputStream
模拟BufferedInputStream
代码:
import java.io.*;
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024*4];
private int pos = 0, count = 0;
MyBufferedInputStream(InputStream in)
{
this.in = in;
}
//一次读一个字节,从缓冲区(字节数组)获取
public int myRead()throws IOException
{
//通过in对象读取硬盘上数据,并存储buf中
if(count==0)
{
count = in.read(buf);
if(count<0)
return -1;
pos = 0;
byte b = buf[pos];
count--;
pos++;
return b&255;
}
else if(count>0)
{
byte b = buf[pos];
count--;
pos++;
return b&0xff;//255的16进制
}
return -1;
}
public void myClose()throws IOException
{
in.close();
}
}
/*
byte: -1 ------> int: -1;
00000000 00000000 00000000 11111111 ------> 11111111 11111111 11111111 11111111
11111111 ---->提升为一个int类型,那不还是-1吗?是-1的
原因是因为在8个1前面补得是1导致的,那么只要在前面补0,
既可以保留原字符数据不变,又可以避免-1的出现。
怎么补0呢?
11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111
----------------------------------------
00000000 00000000 00000000 11111111
write()方法在做强转为byte型 将指定的字节写入此缓冲的输出流
read()方法在做提升
*/
个人总结:掌握字节流和字符流的区别,FileInputStream()和FileOutputStream,以及BufferedInputStream()和BufferedOutputStream()的使用,缓冲区是用于提高读写效率的
了解BufferedInputStream()内部实现原理。其他小知识点:"abc".getBytes() ------>把字符串转成字节 把数组转成字符串输出new String(数组名, start,end)