本文简绍讲解了FileWriter、FileReader、BufferWriter、BufferReader、LineNumReader、FileOutputStream、FileInputStream、BufferInputStream、BufferOutputStream等流操作技术。
————————————————————————————————
1、明确“源”和“目的”:
字节流 字符流
源(输入流):InputStream()、 Reader();
目的(输出):OutputStream()、Reader();
2、明确数据是否“纯文本”:
是:字符流;
否:字节流。
3、明确具体使用对象:
源设备:内存、硬盘、键盘;
目的 : 内存、硬盘、控制台。
————————————————————————————————
1、写文件FileWriter
flush()和close()的区别:
1)flush()刷新流后,将数据写入文件中,流还可以使用;
2)close()关闭流之前,会自动调用flush()刷新流。关闭后,流不能再次使用。
package io.dol.sn;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
//创建对象,就一定要明确被操作的文件。如果该目录下已有同名文件,该文件将被覆盖。
FileWriter fWriter = new FileWriter("demo.txt");
//写入流中,并不是直接写在demo.txt里面
fWriter.write("I's Dolphin");
//刷新流中数据
//fWriter.flush();
fWriter.close();//关闭之前会刷新一次缓冲流
//flush刷新后,流可以继续用
//close之后,流被关闭
}
}
2、对写文件操作添加异常捕捉try:
1)FileWriter()、write()、close()都会产生抛出;
2)我们将close()放在finally里面进行处理;
3)那么,需要将fWriter变量定义在外面,同时需要再重新try一次close();
4)注意,假设创建文件失败,则fWriter=null; 此时进入finally调用close(),异常。所以需要判null。
5)注意,换行需要用“\r\n”实现。
package io.dol.sn;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) {
//需要将申明写在外面,否则finally中会出现变量未定义
FileWriter fWriter = null;
try
{
fWriter = new FileWriter("demo.txt");
//注意换行需要用“\r\n”来实现
fWriter.write("I'm Dolphin.\r\n我叫海豚.");
}
catch (IOException e) {
System.out.println("文件创建失败");
}
finally{
try {//注意:close()要单独try
//同时要对流是否为空进行判断
if (fWriter != null)
fWriter.close();
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
3、读文件FileReader
read()函数,每次读取一个字符,返回值为int。
package io.dol.sn;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader fReader = null;
try
{
fReader = new FileReader("demo.txt");
//read()一次读一个字符,且自动往后移动
int ch = fReader.read();
//System.out.println(ch);
System.out.println((char)ch);
}
catch (IOException e) {
System.out.println("文件读取失败");
}
finally{
try {
if (fReader != null)
fReader.close();
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
改进后1,用个while()循环,每次读取一个字符直到将文件全部读取完毕。
package io.dol.sn;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader fReader = null;
try
{
fReader = new FileReader("demo.txt");
int ch = 0;
//read()一次读一个字符,且自动往后移动
while ((ch = fReader.read()) != -1)
{
//System.out.println(ch);
System.out.print((char)ch);
}
}
catch (IOException e) {
System.out.println("文件读取失败");
}
finally{
try {
if (fReader != null)
fReader.close();
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
改进后2,每次读取一块数据直到将文件读完。这里注意一下,int read(char [])返回值为成功读取到的数据。
package io.dol.sn;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader fReader = null;
try
{
fReader = new FileReader("demo.txt");
//注意,这里随便开辟3个空间,一般开辟为2的整数倍,如1024
char buf[] = new char[3];
int n = 0;
//int read(char[])返回值为读取成功的个数
while ((n=fReader.read(buf)) != -1)
{
System.out.print(new String(buf,0,n));
}
}
catch (IOException e) {
System.out.println("文件读取失败");
}
finally{
try {
if (fReader != null)
fReader.close();
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
4、文件缓冲区之写文件操作BufferedWriter
1)缓冲区的出现,是为了提高流的操作效率;
2)所以,创建缓冲区之前,必须有流;
3)缓冲区提供了一个跨平台是方法:newLine() 这里不做过多说明。
package io.dol.sn;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
//缓冲区的出现,是为了提高流的操作效率;
//所以,创建缓冲区之前,必须有流。
public class BufferWriterDemo {
public static void main(String[] args) {
BufferedWriter bfBufferedWriter = null;
FileWriter fWriter = null;
try
{
//创建一个文件
fWriter = new FileWriter("demo.txt");
//将数据流关联上缓冲区,以后都是直接对缓冲区操作
bfBufferedWriter = new BufferedWriter(fWriter);
bfBufferedWriter.write("I'm Dolphin.\r\n我叫海豚.");
}
catch (IOException e) {
System.out.println("文件创建失败");
}
finally{
try {
if (bfBufferedWriter != null)
{
//凡是牵涉到缓冲区的都需要刷新数据
bfBufferedWriter.flush();
//这里关闭缓冲区,其实就相当于是关闭了数据流
bfBufferedWriter.close();
//fWriter.close() 就不需要调用了
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
5、文件缓冲区之读文件操作BufferedReader
注意:这里的readLine()方法,只返回回车前的内容,并不返回回车符;所以,读取多行的时候,会出现不换行情况。
package io.dol.sn;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferReaderDemo {
public static void main(String[] args) {
BufferedReader bfBufferedReader = null;
FileReader fReader = null;
try
{
//打开一个文件
fReader = new FileReader("demo.txt");
//将数据流关联上缓冲区,以后都是直接对缓冲区操作
bfBufferedReader = new BufferedReader(fReader);
//String readLine()这个方法很牛,一次从文本读取一行数据
String buf = bfBufferedReader.readLine();
System.out.println(buf);
}
catch (IOException e) {
System.out.println("文件创建失败");
}
finally{
try {
if (bfBufferedReader != null)
{
bfBufferedReader.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
改进后,每次读取一行,循环读取,实现读取文件中的所有数据。
package io.dol.sn;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferReaderDemo {
public static void main(String[] args) {
BufferedReader bfBufferedReader = null;
FileReader fReader = null;
try
{
fReader = new FileReader("demo.txt");
bfBufferedReader = new BufferedReader(fReader);
//String readLine()读取到文件末尾返回值为null
String buf = null;
while ((buf=bfBufferedReader.readLine()) != null)
System.out.println(buf);
}
catch (IOException e) {
System.out.println("文件创建失败");
}
finally{
try {
if (bfBufferedReader != null)
{
bfBufferedReader.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
6、跟踪行号缓冲字符输入流LineNumberReader
此类定义了方法getLineNumber(int)和getLineNumber()用于设置行号和获取行号;
package io.dol.sn;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class LineNumberReaderDemo {
public static void main(String[] args) {
LineNumberReader lnReader = null;
FileReader fReader = null;
try
{
fReader = new FileReader("demo.txt");
lnReader = new LineNumberReader(fReader);
String buf = null;
//行号默认是从0开始,我们设置从100开始
lnReader.setLineNumber(100);
while ((buf=lnReader.readLine()) != null)
System.out.println(lnReader.getLineNumber()+":"+buf);
}
catch (IOException e) {
System.out.println("文件创建失败");
}
finally{
try {
if (lnReader != null)
{
lnReader.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
7、字节流操作之写文件FileOutputStream
当我们需要对图片视频等数据进行操作的时候,就需要用到字节流;
package io.dol.sn;
import java.io.FileOutputStream;
import java.io.IOException;
//图片数据就需要用到字节流
public class FileOutputStreamDemo {
public static void main(String[] args) {
FileOutputStream fos = null;
try
{
fos = new FileOutputStream("demo.txt");
//直接对字节流进行操作是不需要刷新的
fos.write("abcde".getBytes());
}
catch (IOException e)
{
System.out.println("文件创建失败");
}
finally
{
try {
if (fos != null)
{
fos.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
8、字节流操作之读文件FileInputStream
推荐用该方法读取数据,后面我讲到的那种方法不推荐;
package io.dol.sn;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try
{
fis = new FileInputStream("demo.txt");
byte[] buf = new byte[1024];
int len = 0;
while ((len=fis.read(buf)) != -1)
{
System.out.println(new String(buf,0,len));
}
}
catch (IOException e)
{
System.out.println("文件创建失败");
}
finally
{
try {
if (fis != null)
{
fis.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
补充一种另外的方法,不推荐使用该方法读取数据。
package io.dol.sn;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try
{
fis = new FileInputStream("demo.txt");
//获得文件大小
int num = fis.available();
//定义一个刚刚好的数组大小,这样以下就不用再for循环读取了;
//但是如何这样的话,一个电影1G大小,难道我们开辟一个这么大的数组?!
byte[] buf = new byte[num];
int len = 0;
while ((len=fis.read(buf)) != -1)
{
System.out.println(new String(buf,0,len));
}
}
catch (IOException e)
{
System.out.println("文件创建失败");
}
finally
{
try {
if (fis != null)
{
fis.close();
}
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}
9、使用字节流实现对文件进行拷贝操作BufferInputStream、BufferOutputStream
1)创建两个流(输入流,输出流);
2)与缓冲区建立关联;(这里只是为了加快拷贝速度,该步骤可省略)。
3)开始拷贝。
下面展示一个mp3拷贝例子:
package io.dol.sn;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//添加缓冲区对字节流进行操作,将1.mp3拷贝为2.mp3
public class BufferIOputStreamDemo {
public static void main(String[] args) {
BufferedInputStream bfi = null;
BufferedOutputStream bfo = null;
try
{
//将两个字节流与缓冲流建立关联
bfi = new BufferedInputStream(new FileInputStream("D:\\1.mp3"));
bfo = new BufferedOutputStream(new FileOutputStream("D:\\2.mp3"));
int byteNum = 0;
//先把硬盘数据弄进缓冲区,read()方法是从缓冲区里取数据
while ((byteNum=bfi.read()) != -1)
{
bfo.write(byteNum);
}
}
catch (IOException e)
{
System.out.println("文件创建失败");
}
finally
{
try {
if (bfi != null)
bfi.close();
if (bfo != null)
bfo.close();
} catch (IOException e2) {
System.out.println("文件关闭失败");
}
}
}
}