---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
IO流的概述
IO流用来处理设备之间的数据传输,
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流。
流按流向分为:输入流,输出流。
字节流:
字节流主要用于操作字节类型的数据,比如图片,视频,音频等执行二进制数据,当然也可以处理文本数据。
字节流的抽象基类:
InputStream ,OutputStream。
字符流:
字符流主要用于处理文本数据,比如:txt文件,XML文件等这些文本文件
字符流的抽象基类:
Reader , Writer。
注:由这四个类是IO流的基类,其派生出来的子类名称都是以其父类名作为子类名的后缀;方式为:功能+父类名称。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
字节流与字符流的区别:
一,字节流操作的数据是字节,字符流操作的数据是字节。
一,字节流在写入操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的;
而字符流在写入操作的时候是使用到缓冲区的。
二,字节流在操作文件时,即使不关闭资源(close方法),文件也能输出;
但是如果字符流不使用close方法,也不使用flush方法的话,则不会输出任何内容,
说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容
那开发中究竟用字节流好还是用字符流好呢?
在所有的硬盘上保存文件或进行传输的时候都是以字节的方法进行的,包括图片也是按字节完成,
而字符是只有在内存中才会形成的,所以使用字节的操作是最多的。
以下是字符流的操作:
FileWriter
创建一个FileWriter对象,该对象一被初始化就必须要明确操作的文。且,该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
但如果在创建流的时候创建的方式是:FileWriter(String fileName, boolean append),将append,设为true就可以将数据添加到文件末尾。
其实该步就是在明确数据要存放的目的地。
字符流在写入的时候,必须要调用Flush方法,将内存中数据写入到文件中去。
字符流在close释放资源之前会调用一次flush方法刷新一次。
注:如果不刷新流,也不关闭流,则文件写入失败!
FileWriter示例代码:
package com.itheima.io.reader_writer;
import java.io.FileWriter;
import java.io.IOException;
/**
* 写入文件
* @author wuyong
*
*/
public class FileWriterDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String name = "D:\\FileWriter.txt";//数据存放目的地,如果不出在则创建一个对应的文件
FileWriter fw = null;
try {
//次方式创建流,文件会被覆盖
// fw = new FileWriter(name);
//创建流对象,这种实例化方式,不会把已有文件的内容覆盖,而是将内容添加到文件末尾
fw = new FileWriter(name,true);
fw.write("123你好!");
fw.append("\r\n再见!");
fw.flush();
}catch(IOException e){
System.out.println("文件不存在");
} finally{
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader
FileReader是与FileWriter 锁对应的字符流读取流,FileWriter 类中读取的时候不需要刷新。
FileWriter类在操作文件的时候文件必须存在,如果文件不存在则运行时报出:FileNotFindException异常。
当读取到文件末尾时,read()方法返回-1。
FileReader示例代码:
package com.itheima.io.reader_writer;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 文件读物
* 其实在每一个文件的末尾处,都有一个结束标识。
* @author wuyong
*
*/
public class FileReaderDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String name = "D:\\IO\\ok.txt";//被读取的文件
FileReader fr = null;
try {
//创建一个读取流对象
fr = new FileReader(name);
//创建一个缓冲区char[]数组chs,长度为1024.
char[] chs = new char[1024];
//调用read方法读取,read方法一次读取一个字符,而且会自动往下读取。
int length = 0;
StringBuilder sb = new StringBuilder();
//如果没有读取到文件末尾,则继续读取。
while ((length = fr.read(chs)) != -1) {
System.out.println("length====" + length);
//将缓冲区char[]数组chs保存到StringBuilder中
sb.append(chs,0,length);
}
System.out.println(sb);//输出文件内容
} catch(IOException e){
System.out.println("文件不存在!");
} finally{
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流复制文件:
package com.itheima.io.reader_writer;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 字符流复制文件
* @author wuyong
*
*/
public class CopyFileDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String src = "C://src.txt";//源文件
String des = "D://des.txt";//目标文件
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter(des);//字符输出流
fr = new FileReader(src);//字符输入流
//方式一:读一个字符,写入一个字符
// int read = 0;
// while ((read = fr.read()) != -1) {
// fw.write(read);
// }
//方式二:定义一个数组缓冲区,每次读取保存到数组中,在一次将数组中的读取到的数据写入目标文件。
char[] chs = new char[1024];
int length = 0;
while ((length = fr.read(chs)) != -1) {
fw.write(chs,0,length);
fw.flush();
}
System.out.println("文件复制成功!");
} catch (IOException e) {
System.out.println("文件不存在!");
} finally {//关闭流
try {
if (fw != null) {
fw.close();
}
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流的缓冲区:
缓冲区的出现可以提高对数据的读写效率。 原理,就是在内中封装了数组。
缓冲区要结合流才可以使用,是在流的基础上对流的功能进行的扩展。
对应类:
1,BufferedWriter类是Writer的子类
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
可以指定缓冲区的大小,或者接受默认的大小。
特有的方法:
void newLine(),另起一行,相当于换行回车符。
该方法可以实现跨平台!因为可以获得不同平台下的换行回车符。该方法是根据JDK安装的版本来确定的。
BufferedWriter示例代码:
package com.itheima.io.charstreambuffer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* @author wuyong
*
*/
public class BufferReaderDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String fileName = "D://Source.txt";//要读取的文件
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));//字符读取缓冲流对象
while (br.read() != -1) {//这个判断也可以。但建议用下面的方式。
System.out.println(br.readLine());
}
while (br.readLine() != null) {//如果读取到文件末尾,则readLine()方法返回null
System.out.println(br.readLine());
}
} catch (IOException e) {
System.out.println("文件不存在!");
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2,BufferedReader类是Reader的子类
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。
特有的方法:String readLine(),一次读取一行。
无论是读一行,获取多个字符。其实最终都是在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。
BufferedReader示例代码:
package com.itheima.io.charstreambuffer;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* BufferWriter写入缓冲类
* @author wuyong
*
*/
public class BufferWriterDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String fileName = "D://Targets.txt";
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(fileName));
bw.write("abc");
bw.newLine();//换行
bw.append("123sff");
bw.flush();//缓冲区写入时!一定要记住刷新!!!
System.out.println("文件写入成功!");
} catch (IOException e) {
System.out.println("文件不存在!");
} finally{
try {
if (bw != null) {
bw.close();//其实关闭缓冲区,就是在关闭缓冲区中的流对象!!!
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符缓冲流复制文件:
package com.itheima.io.charstreambuffer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 通过缓冲区复制文件
* @author wuyong
*
*/
public class BufferCopyDemo {
/**
* @param args
*/
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("C:/src.txt"));
bw = new BufferedWriter(new FileWriter("D:/bufferCopy.txt"));
//方式一:定义一个数组作为缓冲区,中转站。
// char[] chs = new char[1024];
// int length = 0;
// while ((length = br.read(chs)) != -1) {
// bw.write(chs,0,length);
// }
//方式二:用readLine和newLine复制文件
String str = null;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
}
System.out.println("缓冲区复制文件成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if (br != null) {
br.close();
}
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3,LineNumberReader
int getLineNumber() 获得当前行号。默认从0开始。
void setLineNumber() 设置当前行号。
LineNumberReader示例代码:
package com.itheima.io.charstreambuffer;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
/**
* LineNumberReader,带行号读取文本文件
* @author wuyong
*
*/
public class LineNumberReaderDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
LineNumberReader lineNumber = new LineNumberReader(new FileReader("C:\\src.txt"));
String line = null;
while ((line = lineNumber.readLine()) != null) {
System.out.println(lineNumber.getLineNumber() + " : " + line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a
href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------