------- android培训、java培训、期待与您交流! ----------
概念
流:流就是字节序列的抽象概念,能被连续读取数据的数据源和能被连续写入数据的接收端就是流
IO流:用于处理设备上的数据
常用设备:硬盘、内存、键盘录入等
IO流的分类:
1、根据处理的数据类型不同,可分为字节流和字符流。
2、根据流的流向不同,可分为输入流和输出流。
IO体系继承关系图
功能
IO体系具备的最基本的两个功能:读取和写入。
1、字节流:InputStream(读取)和OutputStream(写入)。
2、字符流:Reader(读)和Writer(写)。
字符流基本的读写操作:Reader和Writer
继承关系:
Reader
InputStreamReader
FileReader:专门用于处理文件的字符读取流对象
Writer
OutputStreamReader
FileWriter:专门用于处理文件的字符写入流对象
Reader中的常用方法:
1、int read():读取一个字符,返回读取到的字符。如果已经读到流的末尾,则返回-1;
2、int raad(char[]):将读取到的字符存入指定的字符数组中,返回的是读到字符的个数,如果已经读到流的末尾,则返回-1;
3、close();:关闭流,释放资源。
Writer中的常用方法:
1、write(ch):将一个字符写入到流中。
2、write(char[]):将一个字符数组写入到流中。
3、write(String):将一个字符串写入到流中。
4、flush():将流中的数据刷新到数据目的地,流依然存在。
5、close():关闭流。在关闭资源之前先将流中的数据flush()到数据目的中。
FileReader:
1、用于读取文本文件的流对象。
2、用于关联文本文件。
构造函数:FileReader(String fileName);
在读取流对象被初始化的时候,必须指定一个被读取的文件。
如果文件不存在,则会发生FileNotFoundException
FileWriter:
1、用于处理文本文件
2、该类中有默认的编码表
3、该类中有临时缓冲区
构造函数:FileWriter(String fileName)
在写入流对象初始化时,必须指定一个存储数据的目的地。如果文件不存在,则系统 会创建一个文件。如果文件存在,则会被覆盖。
FileWriter(String fileName,boolean append):
当append为true时,则会在文件的末尾处进行数据的续写。
代码示例:将C盘一个文本文件复制到D盘。
复制的原理:其实就是将C盘下的文件数据存储到D盘的一个文件中。
步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
第一种方法:
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_2();
}
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("SystemDemo_copy.txt");
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
}
}
}
第二种方法:从C盘读一个字符,就往D盘写一个字符。
public static void copy_1()throws IOException
{
//创建目的地。
FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
//与已有文件关联。
FileReader fr = new FileReader("RuntimeDemo.java");
int ch = 0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
字符流的缓冲区:
缓冲区的出现提高了对流的操作效率,其实现的原理就是在内部对数组进行了封装。
对应的对象:
BufferedReader
特有方法:readLine():一次读一行,读到行标记时,就将行标记前的字符串返回,读到末尾时返回null。
BufferedWriter
特有方法:newLine():跨平台的换行符,用于写入一个换行符到流中。
使用缓冲区技术实例:通过缓冲区复制一个.java文件。
import java.io.*;
class CopyTextByBuf
{
public static void main(String[] args)
{
BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{
bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
String line = null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bufw!=null)
bufw.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
字节流的读写操作:
InputStream和OutputStream
字节流可以操作任何数据。
以缓冲区拷贝一段MP3文件的代码为例:
/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
为简化代码,将异常抛出。
*/
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
copy_1();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
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();
}
}
转换流:
特点:
1、是字节流和字符流之间的桥梁。
2、该流对象中可以对读取到的字节数据进行指定编码表的编码转换。
使用范围
1、当字节和字符之间有转换动作时。
2、流操作的数据需要进行编码表的指定时。
具体的对象体现:
1、InputStreamReader:字节到字符的桥梁。
2、OutputStreamWriter:字符到字节的桥梁。
构造函数:
InputStreamReader(InputStream):通过该构造函数初始化,使用的是本系统默认的编码表 GBK。
InputStreamReader(InputStream,String charSet):通过该构造函数初始化,可以指定编码表。
OutputStreamWriter(OutputStream):通过该构造函数初始化,使用的是本系统默认的编 码表GBK。
OutputStreamWriter(OutputStream,String charSet):通过该构造函数初始化,可以指定编码 表。 操作文件的字符流对象是转换流的子类。
转换流中的read方法。已经融入了编码表,在底层调用字节流的read方法时将获取的一个或者多个字节数据进行临时存储,并去查指定的编码表,如果编码表没有指定,查的是默认码表。那么转流的read方法就可以返回一个字符比如中文。转换流已经完成了编码转换的动作,对于直接操作的文本文件的FileReaer而言,就不 用在重新定义了,只要继承该转换流,获取其方法,就可以直接操作文本文件中的字符数据了。
流操作的基本规律:
1、明确数据源和数据目的。其实是为了明确输入流还是输出流。
2、明确操作的数据是否是纯文本数据。其实是为了明确字符流还是字节流。
数据源:键盘System.in, 硬盘(File开头的流对象),内存(数组)。
数据目的:控制台System.out, 硬盘(File开头的流对象),内存(数组)。
本文出自 “点点滴滴” 博客,请务必保留此出处http://arctictern.blog.51cto.com/10120640/1660117
原文地址:http://arctictern.blog.51cto.com/10120640/1660117