java语言的i/o库提供了四大等级结构:InputStream,OutputStream,Reader,Writer四个系列的类。InputStream和OutputStream处理8位字节流数据, Reader和Writer处理16位的字符流数据。InputStream和Reader处理输入, OutputStream和Writer处理输出。大家一定要到J2SE文档中看看这四大等级结构的类继承体系。
除了这四大系列类,i/o库还提供了少数的辅助类,其中比较重要的是InputStreamReader和OutputStreamWriter。InputStreamReader把InputStream适配为Reader, OutputStreamWriter把OutputStream适配为Writer;这样就架起了字节流处理类和字符流处理类间的桥梁。
您使用i/o库时,只要按以上的规则,到相应的类体系中寻找您需要的类即可。(----参考)
输入流和出相对于内存设备而言 输入流和出相对于内存设备而言 .
将外设中 的数据读取到内存:输入
将内存的数写入到外设中:输出。
字节流和符的区别:
1,字节流读取的时候,读到一个字节就返回一个字节。
字符流使用了字节流读到一个或多个字节时,先去查指定的编码表,将查到的字符返回。
2,字节流可以处理所有的数据,如图片,mp3等
而字符流只能处理字符数据
结论:只是出来纯文本数据,要优先考虑使用字符流。除此之外都用字节流。
1.1 IO程序的书写
导入IO包中的类 ,进行IO异常处理,在finally中对流进行关闭
ReaderReader
|-- InputStreamReader
|-- FileReader:。 专门用于处理文件的字符读取流对象。
Writer
|---OutputStreamWriter
---- FileWriter:专门用于处理文件的字符输入流对象
1.2.1 字符流——创建文件,
创建流对象,建立数据存放文件
FileWriter fw = new FileWriter(“test.txt”);
调用流对象的写入方法,将数据写入流
fw.write(“text”);
关闭流资源,并将流中的数据清空到文件中
fw.close();
案例代码:
package bbs.itheima.com;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args){
FileWriter fw = null;
try{
fw = new FileWriter("test.txt");
fw.write("text");
}
catch (IOException e){
System.out.println(e.toString());
}
finally{
if(fw!=null)
try{
fw.close();
}
catch (IOException e){
System.out.println(e.toString());
}
}
}
}
1.2.2 字符流——读取文件
建立一个流对象,将已存在的一个文件加载进 流。
FileReader fr = new FileReader(“Test.txt”);
创建一个临时存放数据的数组。
char[] ch = new char[1024];
调用流对象的读取方法将流中的数据读入到数组 中。
fr.read(ch);
源代码:
package bbs.itheima.com;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
/**
* @param args
*/
public static void main(String[] args) {
FileReader fr = null;
try{
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len= 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
}
catch (IOException e){
System.out.println("read-Exception :"+e.toString());
}
finally{
if(fr!=null){
try{
fr.close();
}
catch (IOException e){
System.out.println("close-Exception :"+e.toString());
}
}
}
}
}
注意:
定义文件路径时,可以用“/”或者“\\”。
在创建一个文件时,如果目录下有同名文 件将被覆盖。
在读取文件时,必须保证该文件已存在, 否则出异常。
关于流的一个案例:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyTest {
/**
* 将C盘一个文件复制到D盘
* 复制原理:其实就是将C盘下的文件数据存储到D盘的一个文件中。
*
* 步骤:
* 1,在D盘创建一个文件,用于存储C盘文件中的数据。
* 2,定义一个读取流和C盘文件关联。
* 3,通过不断的读写完成数据存储
* 4,关闭资源。
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//copy_1();
copy_2();
}
public static void copy_1() throws IOException
{
//创建目的地
FileWriter fw=new FileWriter("c:\\lc.txt");
//与已有文件关联
FileReader fr=new FileReader("demo.txt");
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
//result: 成功复制
}
public static void copy_2()
{
FileWriter fw=null;
FileReader fr=null;
try {
fw=new FileWriter("c:\\li.txt");
fr=new FileReader("demo.txt");
char[]buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
} catch (IOException e) {
//e.printStackTrace();
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
{
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fw!=null)
{
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//result: 成功复制
}
}
字符流的缓冲区:
缓冲区的出现提高了对数据的读写效率。
原理:其实就是将数组进行封装。
对应类
BufferedWriter
特有的方法:newLine():跨平台换行符
写入缓冲区对象。
// 建立缓冲区对象必须把流作为参数传递给的构造函。
BufferedWriter buf = new BufferedWriter(new FileWriter("BufferedDemo.txt");
buf.write("abc");//将数据写入到缓冲区
buf.flush();//对缓冲区进行刷新,将数据刷新到母的地中
buf.close();//关闭缓冲区。
案例:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
/**
* 缓冲区的出现 是为了提高流的操作效率而出现的。
* 所以在创建缓冲区之前,必须要现有流对象。
*/
public static void main(String[] args) {
// 创建一个字符写入流对象
FileWriter fw=null;
try {
fw=new FileWriter("c:\\BufferedDemo.txt");
//为了提高字符写入流效率。加入了缓冲技术
//只要将需要提高效率的流对象作为参数传递给缓冲区的构造函数即可
BufferedWriter bw=new BufferedWriter(fw);
bw.write("abcde");
bw.newLine(); //跨平台换行符
//记住,只要用到缓冲区,就要记得刷新
//bw.flush();
//其实关闭缓冲区就是在关闭缓冲区的流对象。
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader
特有的方法:readlLine():一次读取一行,到行标记时,将行标记之前的字符数据作为
字符串返回,当读到末尾时返回null。
用缓冲区方法 读写文件:
缓冲区要结合流才可以使用。
在流的基础上对流的功能进行了增强。
读取缓冲区对象:
BufferedReader buf = new BufferedReader(new FileReader("demotxt");
案例:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/* 字符读取流缓冲区
该缓冲区提供了一次毒一行的方法readline,方便对文本数据的获取。
当返回null时读到文件末尾。*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建一个读取流对象和文件相关联
FileReader fr=new FileReader("demo.txt");
//为了提高效率,加入缓冲技术,将字符流读取对象作为参数传递给缓冲对象的构造函数
BufferedReader br=new BufferedReader(fr);
String line=null;
while((line=br.readLine())!=null)
{
System.out.println(line);
}
}
}
转换流:InputStreamReader,OutputStreamWriter
转换流的由来,字符流与字节流之间的桥梁,方便了字符流与字节流之间的操作。
转换流的应用
字节流中的数据都是字符时,转成字符流操作更高效。
代码的体现:
标准输入输出流
System类中的字段:in,out。它们各代表了系统标准的输入和输出设备。
默认输入设备是键盘,输出设备是显示器。
System.in的类型是InputStream.
System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类.
流的基本应用:
流是用来处理数据的。
处理数据时,一定要先明确数据源,与数据目的 地(数据汇)。
数据源可以是文件,可以是键盘,数据目的地可以是文件、显示器或者其他设备。
而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理.转换处理等。
此图参考传智播客课件:
综合案例”:
import java.io.FileReader;
import java.io.IOException;
public class MyBufferedReader {
private FileReader r;
public MyBufferedReader(FileReader r)
{
this.r=r;
}
/*
* 明白了 BufferedReader.readLine()的原理后
* 可以自定义一个类中包含一个功能和readLine一致的方法来模拟 BufferedReader
*/
//可以一次读一行数据的方法
public String myReadLine() throws IOException
{
//定义一个临时容器。原BufferedReader封装的是字符数组。
//定义一个StringBuilder,因为最终还要讲数据变成字符串,
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
//最后一行无换行标记
if(sb.length()!=0)
{
return sb.toString();
}
//读到结尾
return null;
}
public void myClose() throws IOException
{
r.close();
}
public static void main(String[] args) {
FileReader fr=null;
MyBufferedReader mr=null;
try {
fr=new FileReader("demo.txt");
mr=new MyBufferedReader(fr);
String line=null;
while((line=mr.myReadLine())!=null)
{System.out.println(line);}
}
catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
File类:
用来将文件或者文件夹封装成对象
方便对文件与文件夹的属性信息进行操作 。
File对象可以作为参数传递给流的构造函数。
File类常见方法:
1. 创建:如果地址中已存在这个文件,那么就不再创建
boolean createNeaFile(); 创建文件
boolean mkdir(); 创建文件夹
boolean mkdirs(); 创建多级文件夹
2. 删除:
Boolean delete(); 删除文件
Boolean deleteOnExit() ; 在程序结束的时候删除文件
3. 判断:
Boolean exists(); 文件是否存在
isFile(); 是否是文件
isDirectory是否是目录
isHidden();是否隐藏
在判断是什么类型的文件之前,一定要先判断文件是否存在
4. 获取:
getAbsolutePath()
获取绝对路径
getPath()
获取路径
getParent()
获取绝对路径中的父目录,如果是相对路径,就返null
File中的List,用于得到指定目录下的文件名称
File[ ] listRoots( );返回一个File数组,得到所有可用的盘符
String [ ] list( ); 返回一个字符串数组,得到所有此路径下的文件,包含隐藏文件 .调用list的对象必须是一个存在的目录
File[]
listFiles():
返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
File[]listFiles(FilenameFilter filter):
通过过滤器放回指定目录下的指定文件
List
和listFiles的区别就是:list返回的只是文件名称,而listFiles返回的是文件对象名称,通过这些对象名称可以得到路径,大小等信息
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。
;