------- android培训、java培训、期待与您交流! ----------
IO流
Java中的IO操作用来处理设备间的数据传输。IO流按流向可分为输入流和输入流;而按操作的数据可分为字节流和字符流。起初先有有字节流,后来为了方便人们操作,将字节编码制成了编码表,由此在字节流的基础上利用编码表而产生了字符流。
Java的IO流中主要由四个基类:
Writer,Reader:所有字符流的基类
InputStream,OutputStream:所有字节流的基类
字符流
字符流是从Writer和Reader派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。
Writer
体系结构:
|-------Writer
|---OutputStreamWriter:字符流通向字节流的桥梁,可以指定编码
|--FileWriter:文件写入流,会创建一个文件,通过构造函数定义是续写还是覆盖
|----BufferedWriter:字符写入流,定义了缓冲区,可以提高效率
FileWriter示例
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args)
{
FileWriter fw = null;
try
{
fw = new FileWriter("demo.txt");
fw.write("abcdefg");
}
catch (IOException e)
{
System.out.println("catch:"+e.toString());
}
finally
{
try
{
if(fw!=null)
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}
Reader
体系结构:
|--------Reader
|----InputStreamReader:字节流通向字符流的桥梁,可以指定编码
|--FileReader:文件读取流,文件需存在,否则抛出异常
|----BufferedReader:字符读取流,定义了缓冲区,可以提高效率
FileReader示例
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("demo.txt");
//定义一个字符数组。用于存储读到字符。
//该read(char[])返回的是读到字符个数。
char[] buf = new char[1024];
int num = 0;
while((num=fr.read(buf))!=-1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
}
}
字节流
字节流是从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。
字节流示例
/*需求,想要操作图片数据。这时就要用到字节流。
复制一个图片.
*/
import java.io.*;
class FileStream
{
public static void main(String[] args) throws IOException
{
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
{
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();
}
}
缓冲区
缓冲区的出现减少了对read和write的调用,提高了对数据的读写效率。不过它要结合流才可以使用,它在流的基础上对流的功能进行了加强。
缓冲区实例
BufferedReader:
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个读取流对象和文件相关联。
FileReader fr = new FileReader("buf.txt");
//为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null)
{
System.out.print(line);
}
bufr.close();
}
}
BufferedWriter:
import java.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个字符写入流对象。
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率。加入了缓冲技术。
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw);
for(int x=1; x<5; x++)
{
bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}
//记住,只要用到缓冲区,就要记得刷新。
//bufw.flush();
//其实关闭缓冲区,就是在关闭缓冲区中的流对象。
bufw.close();
}
}
BufferedOutputStream和BufferedInputStream:
/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
copy_2();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_2()throws IOException
{
MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));
int by = 0;
//System.out.println("第一个字节:"+bufis.myRead());
while((by=bufis.myRead())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.myClose();
}
//通过字节流的缓冲区完成复制。
public static void copy_1()throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
int by = 0;
while((by=bufis.read())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
}
流操作的基本规律
IO操作最头痛的是如何其体系中选择需要的类,这个过程可以通过三个步骤来完成:
1.明确源和目的。
源:输入流,InputStream和Reader;
目的:输出流,OutputStream和Writer
2.明确操作的数据是否是纯文本。
是:字符流
不是:字节流。
3.当体系明确后,再明确要使用哪个具体的对象。
通过设备来区分:
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台。
此外:
如果需要提高效率,则换用对应的缓冲区。
如果需要指定编码,则换用对应的转换流。