——- android培训、java培训、期待与您交流! ———-
io流用来处理设备之间的数据传输,java对数据的操作是通过流的方式,java用于操作流的对象都在io包中。
io常用基类-字符流
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer.
需求:在硬盘上,创建一个文件并写入一些文字数据
找到一个专门用于操作文件的Writer子类对象:FileWriter,后缀名是父类名。前缀名是该流对象的功能。
package io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWtiterDemo {
public static void main(String[] args) throws IOException {
/*
* 创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件
* 而且该文件会被创建到指定目录下,如果该目录下已存在该文件会被覆盖,
* 其实该步就是在明确数据要存放的目的地。
*/
FileWriter fw= new FileWriter("demo.txt");
//调用write方法,将字符写入到流中
fw.write("abcdef");
//刷新流对象中的缓冲中的数据,将数据刷到目的地
fw.flush();
//关闭流资源,但是在关闭之前会刷新一次内部的缓冲区中数据,将数据刷到目的地中‘
//和flush区别:flush刷新后,流可以继续使用close刷新后,会将流关闭。
//fw.close();
}
}
IO异常的处理方式
package io;
import java.io.FileWriter;
import java.io.IOException;
public class IoExceptionDemo {
public static void main(String[] args) {
//建立引用,作用于全局
FileWriter fw=null;
try {
fw=new FileWriter("c:\\demo.txt");
fw.write("abcd");
} catch (IOException e) {
e.printStackTrace();
}
finally
{
//最后再处理一次
try {
//为了提高健壮性,需再次判断。
if(fw!=null )
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件的续写
package io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo1 {
public static void main(String[] args) {
FileWriter fw=null;
try {
//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写。
fw=new FileWriter("c:\\demo.txt",true);
// \r\n为回车换行
fw.write("aaa\r\nccc");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件的读取
读取方式一:
package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr=null;
try {
//创建一个文件读取流对象,和指定名称的文件相关联, 要保证文件时存在的,如果不存在,会发生异常FileNotFoundExcetion
fr=new FileReader("c:demo.txt");
int ch=0;
//read():一次读一个字符,而且会自动往下读
while((ch=fr.read())!=-1)
{
System.out.println((char)ch);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
fr.close();
}
}
}
读取方式二:
package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo1 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("c:\\demo.txt");
char[] buf=new char[1024];
int num=0;
while((num=fr.read(buf))!=-1)
{
System.out.println(new String(buf,0,num));
}
fr.close();
}
}
练习:
package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//将c盘一个文本文件复制到D盘
package io;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//将c盘一个文本文件复制到D盘
public class CopyTest {
public static void main(String[] args) {
//创建一个文件读取和写入对象
FileReader fr=null;
FileWriter fw=null;
try {
fr=new FileReader("c:\\ExceptionDemo.java");
fw=new FileWriter("d:\\Test.txt");
char[] buf=new char[1024];
int num=0;
while((num=fr.read(buf))!=-1)
{
//写入指定文件
fw.write(buf,0,num);
}
} catch (IOException e) {
throw new RuntimeException("读写失败");
}
finally
{
try {
if(fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
**字符流缓冲区**
缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要先有流对象。
字符写入缓冲区:
package io;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("c:\\buf.txt");
BufferedWriter bf=new BufferedWriter(fw);
bf.write("asghh");
//换行
bf.newLine();
bf.write("cccc");
//用到缓冲区就要刷新
bf.flush();
bf.close();
}
}
![这里写图片描述](https://img-blog.csdn.net/20150715181922491)
**字符读取缓冲区**
该缓冲区提供了一个一次读一行的方法: readLine(),方便于对文本数据的获取,当返回null时,表示读到文件末尾。
package io;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建一个读取流对象和文件相关联
FileReader fr=new FileReader("c:\\buf.txt");
//将字符读取流对象错位参数传入缓冲对象的构造函数
BufferedReader br=new BufferedReader(fr);
String line=null;
while((line=br.readLine())!=null)
{
System.out.println(line);
}
br.close();
}
}
![这里写图片描述](https://img-blog.csdn.net/20150715183047321)
package io;
/*
* 利用缓冲区复制文件
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedTest {
public static void main(String[] args) {
BufferedReader bfr=null;
BufferedWriter bfw=null;
try {
bfr=new BufferedReader(new FileReader("c:\\ExceptionDemo.java"));
bfw=new BufferedWriter(new FileWriter("c:\\bufText.txt"));
String len=null;
while((len=bfr.readLine())!=null)
{
bfw.write(len);
bfw.newLine();
bfw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
if(bfr!=null)
bfr.close();
} catch (IOException e) {
throw new RuntimeException("读取流关闭异常");
}
try {
if(bfw!=null)
bfw.close();
} catch (IOException e) {
throw new RuntimeException("写入流关闭异常");
}
}
}
}
根据readLine原理(FileReade中的read方法)可以自定义一个类模拟一下BufferedReader.
package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
class MyBufferedReader
{
private FileReader fr;
MyBufferedReader(FileReader fr)
{
this.fr=fr;
}
//可以一次读一行的方法
public String myReadLine() throws IOException
{
//定义一个临时容器
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.read())!=-1)
{
if(ch==’\r’)
continue;//继续回到while循环判断
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
{
fr.close();
}
}
public class MyBufferedReaderTest {
public static void main(String[] args) {
MyBufferedReader myr=null;
try {
myr=new MyBufferedReader(new FileReader("c:\\buf.txt"));
String len=null;
while((len=myr.myReadLine())!=null)
{
System.out.println(len);
}
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
myr.myClose();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
![这里写图片描述](https://img-blog.csdn.net/20150715221041589)
**装饰设计模式**
当想要对已有的对象进行功能增强时,可以定义类,将已有的对象传入,基于已有功能,并提供加强功能,那么自定义类的该类称为装饰类。
示例:
package io;
class Person
{
public void chifan()
{
System.out.println(“吃饭”);
}
}
class SuperPerson
{
private Person p;
SuperPerson(Person p)
{
this.p=p;
}
public void superChifan()
{
System.out.println(“开胃酒”);
p.chifan();
System.out.println(“甜点”);
System.out.println(“来一根”);
}
}
public class ZhuangShiDemo {
public static void main(String[] args) {
Person p=new Person();
SuperPerson s=new SuperPerson(p);
s.superChifan();
}
}
![这里写图片描述](https://img-blog.csdn.net/20150715222900570)
装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以
装饰类和被装饰类通常是不属于一个体系中的。
**LineNumberReader**
package io1;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class LineNumberReaderDemo {
public static void main(String[] args) throws IOException {
LineNumberReader lir=new LineNumberReader(new FileReader("c:\\buf.txt"));
String line=null;
while((line=lir.readLine())!=null)
{
System.out.println(line);
}
lir.close();
}
}
![这里写图片描述](https://img-blog.csdn.net/20150716095837051)
根据LineNumberReader原理,创建类模拟
package io1;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
class MyLineNumberReader
{
private FileReader fr;
private int LineNumber;
MyLineNumberReader(FileReader fr)
{
this.fr=fr;
}
public void setLineNumber(int LineNumber)
{
this.LineNumber=LineNumber;
}
public int getLineNumber()
{
return LineNumber;
}
public String myReadLine() throws IOException
{
LineNumber++;
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.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 muClose() throws IOException
{
fr.close();
}
}
public class MyLineNumberReaderTest {
public static void main(String[] args) throws IOException {
MyLineNumberReader mln=new MyLineNumberReader(new FileReader("c:\\buf.txt"));
String line=null;
while((line=mln.myReadLine())!=null)
{
System.out.println(mln.getLineNumber()+line);
}
}
}
![这里写图片描述](https://img-blog.csdn.net/20150716111142908)
**字节流**
字节流的写入与其三种读取方式:
package io1;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//writeFile();
//readFile_1();
//readFile_2();
readFile_3();
}
//available。特有的读取方式
public static void readFile_3() throws IOException
{
FileInputStream fis=new FileInputStream("c:\\fox.txt");
byte[] buf=new byte[fis.available()];//定义一个刚刚好的缓冲区,不用循环了,但是如果文件多大或导致内存溢出,所以不常用
fis.read(buf);
System.out.println(new String(buf));
}
//读取数组
public static void readFile_2() throws IOException
{
FileInputStream fis=new FileInputStream("c:\\fox.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("c:\\fox.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("c:\\fox.txt");
fos.write("acbbb".getBytes());
fos.close();
}
}
![这里写图片描述](https://img-blog.csdn.net/20150716124148038)
练习:通过字节流复制mp3文件
package io1;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public 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:\\匆匆那年.mp3"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("c:\\copy匆匆.mp3"));
int by=0;
while((by=bufis.read())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
}
**键盘录入**
读取键盘录入
System.out对应的是标准输出设备,控制台
System.in对应的是标准输入设备,键盘
需求:通过键盘录入数据,当录入一行数据后,就将改行数据进行打印,如果录入的数据时over,那么久停止录入。
package io;
import java.io.IOException;
import java.io.InputStream;
public class ReadIn {
public static void main(String[] args) throws IOException {
InputStream in=System.in;
int by=in.read();
StringBuilder sb=new StringBuilder();
while(true)
{
int ch=in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s=sb.toString();
if("over".equals(s))
break;
System.out.println(s);
sb.delete(0,sb.length());
}
else sb.append((char)ch);
}
}
}
![这里写图片描述](https://img-blog.csdn.net/20150716212702747)
使用bufferedReader中readline方法更方便:
package io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class TransStreamDemo {
public static void main(String[] args) throws IOException {
InputStream in=System.in;
InputStreamReader ins=new InputStreamReader(in);
BufferedReader buf=new BufferedReader(ins);
String line=null;
while((line=buf.readLine())!=null)
{
if(line.equals("over"))
break;
System.out.println(line);
}
}
}
![这里写图片描述](https://img-blog.csdn.net/20150718095700352)
练习一:
package io1;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
//需求:把键盘录入的数据存储到一个文件中。
public class ShuruShuchuTest {
public static void main(String[] args) throws IOException {
//键盘录入
BufferedReader bur=new BufferedReader(new InputStreamReader(System.in));
//输出
BufferedWriter buw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\out.txt")));
String line=null;
while((line=bur.readLine())!=null)
{
if(line.equals("over"))
break;
buw.write(line);
buw.newLine();
buw.flush();
}
bur.close();
buw.close();
}
}
“`
通过三个明确确定应该使用哪个流对象
1。明确源和目的:
源:输入流 InputStream Reader
目的:输出流 outputStream writer
2.操作的数据是否是纯文本
是:字符流
不是:字节流
3.当体系明确后,再明确要使用哪个具体的对象。
通过设备进行区分:
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台。