黑马程序员——Java基础——IO流(一)

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

IO流:
package cn.fuxi._06io;
/**
 * IO流:
 * IO流用来处理设备之间数据的传输,Java对数据的操作是通过流的方式.Java用于
 * 操作流的对象都在IO包中.
 * 输入流和输出流相对于内存设备而言.
 * 
 * 将外设中的数据读取到内存中:输入.
 * 将内存的数据写入到外设中:输出.
 * 
 * 流按操作数据分为两种:字节流和字符流.
 * 
 * 字符流的由来:
 * 其实就是:字节流读取文字字节数据后,不直接操作,而是先查指定的编码表,获取对应的文字.
 * 再对这个文字经行操作.
 * 简单说:字节流+编码表
 * 
 * 
 * IO常用基类-字符流:
 * 字节流的抽象基类:InputStream,OutputStream.
 * 字符流的抽象基类:Reader,Writer.
 * 
 * P.S.
 * 由着四个类派生出来的子类名称都是以其父类名作为子类名的后缀.
 * 如:InputStream的子类FileInputStream.
 * 如:reader的子类FileReader.
 */
/*
 * 需求:将一些文字存储到硬盘一个文件中.
 * 注意:如果要操作文字数据,优先考虑字符流.
 * 而且要将数据从内存写到硬盘上,要使用字符输出流:Writer.
 * 硬盘的数据基本体现是文件,希望找到一个可以操作文件的Writer:FileWriter.
 * 
 */
import java.io.*;

public class _01FileWriterDemo {

	public static void main(String[] args) {
		//创建一个可以往文件中写入字符数据的字符输出流对象
		//既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件用于存储数据的目的.
		//如果文件不存在,则会自动创建
		//如果文件存在,则会被覆盖
		try {
			FileWriter fw = new FileWriter("IoDemo.txt");
			//调用Writer对象中的write(String s)方法,写入数据
			//数据暂时被写入到临时存储缓冲区中
			fw.write("我不会告诉你我的马甲名字其实就是传说中的传奇查");
			//进行刷新,将数据直接写入到目的地中
			fw.flush();
			//关闭流,关闭资源,在关闭前会先调用flush刷新缓冲中数据到目的地.
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
		}
	}

}
输出结果:



package cn.fuxi._06io;
/**
 * 如果构造函数中加入true,可以实现对文件进行续写.
 */
import java.io.*;

public class _02FileWriterDemo{
	public static void main(String[] args){
		try {
			FileWriter fw = new FileWriter("IoDemo.txt",true);
			fw.write("\r\n我传奇查有100种方法让你在IT界混不下去!");
			fw.flush();
			fw.write("糖宝~");
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
输出结果:

package cn.fuxi._06io;
/**
 * IO流的异常处理方式:为防止代码异常导致流无法关闭,因此在finally中对流经行关闭
 */
import java.io.*;
public class _03FileWriterDemo {
	public static void main(String[] args) {
		FileWriter fw = null;
		try {
			fw = new FileWriter("IoDemo.txt",true);
			fw.write("啦啦啦~种太阳~");
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				fw.close();
			} catch (IOException e) {
				throw new RuntimeException("关闭失败");
			}
		}
	}

}

package cn.fuxi._06io;
/**
 * 需求:读取一个文件,将读取的字符打印到控制台(使用FileReader)
 * 第一种读取方式:使用read()方法读取文本文件数据.
 */
import java.io.*;
public class _04FileReaderDemo {

	public static void main(String[] args) {
		FileReader fr =null;
		try {
			fr = new FileReader("IoDemo.txt");
			//用Reader中的read()方法读取字符
			int ch = 0;
			while((ch = fr.read())!=-1){//作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1 
				System.out.print((char)ch);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~

package cn.fuxi._06io;
/**
 * 第二种读取方式:使用read(char[])方法读取文本文件数据.
 */
import java.io.*;
public class _05FileReaderDemo {
	public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("IoDemo.txt");
			//使用read(char[])读取文本文件数据
			//先穿件字符数组
			char[] buf = new char[1024];
			int len = 0;
			while((len=fr.read(buf))!=-1){
				System.out.println(new String(buf,0,len));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~

package cn.fuxi._06io;
/**
 * 练习:
 * 		将d盘的一个文本文件复制到c盘
 * 分析:	读取d盘的IoDemo.txt文件中的数据,将这些数据写入到c盘copyText_1.txt文件中.
 * 		既然是操作文本数据,使用字符流.
 * 方式1:使用read()读取文本文件数据.
 * 方式2:使用read(char[])读取文本文件数据.
 */
import java.io.*;
public class _06FileReaderTest {
	public static void main(String[] args) {
		method_1();
		method_2();
		
	}
	public static void method_1(){
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("IoDemo.txt");
			fw = new FileWriter("Copy_IoDemo.txt");
			int ch;
			while((ch = fr.read())!=-1){
				fw.write(ch);//可以看到,字符型数据传输的本质本质也是数字传输,ch的类型为Int
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public static void method_2(){
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("IoDemo.txt");
			fw = new FileWriter("Copy2_IoDemo.txt");
			char[] ch = new char[1024];
			int len = 0;
			while((len=fr.read(ch))!=-1){
				fw.write(ch,0,len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try{
				fw.close();
			}catch(IOException e){
				e.printStackTrace();
			}
			try{
				fr.close();
			}catch(IOException e){
				e.printStackTrace();
			}
		}	
	}
}
输出结果:
黑马程序员——Java基础——IO流(一)_第1张图片

package cn.fuxi._06io;
/**
 * 字符串缓冲区
 * 缓冲区的出现提高了对数据的读写效率.
 * 
 * 对应类:
 * BufferedWriter
 * BufferedReader
 * 
 * P.S.
 * 缓冲区要结合流才可以使用.
 * 
 * 作用:在流的基础上对流的功能进行了增强.提高写入效率,使用缓冲区.
 */
import java.io.*;
public class _07BufferedWriter {
	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("buff.txt");
		//为了提高写入效率,使用字符流的缓冲区.
		//创建了一个字符写入流的缓冲区对象,并且指定与要被缓冲的流对象想关联
		BufferedWriter bufw = new BufferedWriter(fw);
		for (int i = 0; i <= 4; i++) {
			//使用缓冲区的写入方法,将数据写入到缓冲区中.
			bufw.write("abcdef"+i);
			//写入内容换行方法:newLine();
			bufw.newLine();
			bufw.flush();
		}
		//使用缓冲区的刷新方法将数据刷入目的地中
		bufw.flush();
		//关闭缓冲区,其实关闭的就是被缓冲的流对象
		fw.close();
	}

}
输出结果:
黑马程序员——Java基础——IO流(一)_第2张图片

package cn.fuxi._06io;
/**
 * 提高读取效率,使用缓冲区
 */
import java.io.*;
public class _08BufferedReader {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("buff.txt");
		BufferedReader bf = new BufferedReader(fr);
		String line = null;
		while((line = bf.readLine())!=null){
			System.out.println(line);
		}
		bf.close();
	}

}
输出结果:
abcdef0
abcdef1
abcdef2
abcdef3
abcdef4

package cn.fuxi._06io;
/**
 * 字符流缓冲区:
 * 写入换行使用BufferedWriter类中的newLine()方法.
 * 读取一行数据使用BufferedReader类中的readLine()方法.
 * 
 * br.read():这个read方法是从缓冲区中读取字符数据,所以覆盖了父类中的read方法.
 * br.readLine():另外开辟了一个缓冲区,存储的是原缓冲区一行的数据,不包含换行符.
 * 
 * 原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前
 * 的缓冲数据变成字符串返回.
 * 
 */
import java.io.*;

public class _09BufferedReaderWriter {
	public static void main(String[] args) throws Exception{
		FileReader fr = new FileReader("buff.txt");
		BufferedReader br = new BufferedReader(fr);		
		FileWriter fw = new FileWriter("Copy_buff.txt");
		BufferedWriter bw = new BufferedWriter(fw);	
		//方式一:一行一行读写
		/*
		String line = null;		
		 while((line=br.readLine())!=null){
			bw.write(line);
			bw.newLine();//写一行要换一行,不然会黏在一起
			bw.flush();;
		}
		*/	
		//方式二:一个一个读写
		int ch=0;
		while((ch=br.read())!=-1){
			bw.write(ch);
			bw.flush();//flush不写会空白
		}
		bw.close();
		br.close();
	}
}
输出结果:
黑马程序员——Java基础——IO流(一)_第3张图片

package cn.fuxi._06io;
/**
 * LineNumberReader
 * 跟踪行号的缓冲字符输入流.此类定义了方法setLineNumber(int)和getLineNumber();
 * 他们可分别用于设置和获取当前行号.
 */
import java.io.*;

public class _10LineNumberReader {
	public static void main(String[] args) throws IOException{
		FileReader fr = new FileReader("D:\\develop\\workspace\\fuxi4\\src\\cn\\fuxi\\_06io\\_10LineNumberReader.java");
		LineNumberReader lnr = new LineNumberReader(fr);
		
		String line = null;
		lnr.setLineNumber(100);
		while((line = lnr.readLine())!=null){
			System.out.println(lnr.getLineNumber()+":"+line);
		}
		lnr.close();
	}
}
输出结果:
101:package cn.fuxi._06io;
102:/**
103: * LineNumberReader
104: * 跟踪行号的缓冲字符输入流.此类定义了方法setLineNumber(int)和getLineNumber();
105: * 他们可分别用于设置和获取当前行号.
106: */
107:import java.io.*;
108:
109:public class _10LineNumberReader {
110: public static void main(String[] args) throws IOException{
111: FileReader fr = new FileReader("D:\\develop\\workspace\\fuxi4\\src\\cn\\fuxi\\_06io\\_10LineNumberReader.java");
112: LineNumberReader lnr = new LineNumberReader(fr);
113:
114: String line = null;
115: lnr.setLineNumber(100);
116: while((line = lnr.readLine())!=null){
117: System.out.println(lnr.getLineNumber()+":"+line);
118: }
119: lnr.close();
120: }
121:}

package cn.fuxi._06io;
/**
 * 对原有类进行了功能的改变,增强.
 */
class Person{
	void chiFan(){
		System.out.println("吃饭啦!!!");
	}
}
//采用装饰的方式增强Person类
//这个类的出现是为了增强Person而出现的
class NewPerson{
	private Person p;
	NewPerson(Person p){
		this.p = p;
	}
	public void chiFan(){
		System.out.println("开胃菜");
		p.chiFan();
		System.out.println("甜点");
	}
}
//采用继承的方式增强Person类
class NewPerson2 extends Person{
	public void chiFan(){
		System.out.println("来瓶1982的拉菲!");
		super.chiFan();
		System.out.println("来瓶卡斯特!");
	}
}

public class _11ZhuangShiDemo {
	public static void main(String[] args) {
		Person p = new Person();
		p.chiFan();
		System.out.println("-------------------");
		NewPerson np = new NewPerson(p);
		np.chiFan();
		System.out.println("-------------------");
		NewPerson2 np2 = new NewPerson2();
		np2.chiFan();
	}
}
/*
 *装饰和继承都可以对功能进行拓展,两者之间有何区别呢?
 *装饰较为灵活,可以不产生继承关系.
 *装饰像缓冲一样可以和具体对象相结合
 *可以将缓冲功能进行单独的封装,哪个对象需要缓冲就关联哪个对象 
 */
 
输出结果:
吃饭啦!!!
-------------------
开胃菜
吃饭啦!!!
甜点
-------------------
来瓶1982的拉菲!
吃饭啦!!!
来瓶卡斯特!

package cn.fuxi._06io;
/**
 * 首先由一个继承体系:
 * Writer
 * 		|--TextWriter:用于操作文本.
 * 		|--MediaWriter:用于操作媒体.
 * 	如果想要对操作的动作进行效率的提高,按照面向对象,可以通过继承的方式对具体的
 * 对象进行功能的拓展,那么就需要加入缓冲技术.
 * Writer
 * 		|--TextWriter:用于操作文本.
 * 			|--BufferTextWriter:加入了缓冲技术的操作文本的对象.
 * 		|--MediaWriter:用于操作媒体
 * 			|--BufferMediaWriter:加入了缓冲技术的操作媒体的对象.
 * 以上方式并不理想,如果这个体系需要再进行功能扩展,又多了更多流对象.
 * 这样就好发现只为了提高功能,导致继承体系越来越臃肿,不够灵活.
 * 
 * 重新思考问题:
 * 既然都是加入的同一种技术----缓冲.
 * 前一种是让缓冲和自己的流对象相结合.
 * 可不可以将缓冲经行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲相关联.
 */
/*
import java.io.*;
class Buffer{
	Buffer(TextWriter w){}
	Buffer(MediaWriter w){}
}
//简化为
class BufferedWriter extends Writer{
	BufferedWriter(Writer){}
}
*/
/**
 * Writer
 * 	|--TextWriter:用于操作文本
 * 	|--MediaWriter:用于操作媒体
 * 	|--BufferedWriter:用于提高效率
 * 
 * 可见:装饰比继承更灵活.
 * 特点:装饰类和被装饰类都必须所属同一个接口或父类.
 */

package cn.fuxi._06io;
/**
 * 练习:
 * 		自定义一个读取缓冲区类,模拟一个BufferedReader.
 * 分析:
 * 		缓冲区中无非就是封装了一个数组,并对外提供了更多的方法对数组经行访问
 * 		其实这些方法最终操作的都是数组的角标.
 * 缓冲的原理:
 * 		其实就是从源中获取一批数据到缓冲区中,再从缓冲区中不断的取出一个一个数据.
 * 		在此次取完后,再从源中继续取一批数据进入缓冲区,当源中的数据被取完时,用-1作为结束标记.
 */
import java.io.*;

class MyBufferedReader{
	private Reader r;
	//定义一个数组作为缓冲区
	private char[] buf = new char[1024];
	//定义一个指针用于操作这个数组中的元素,当操作到最后一个元素后,指针应该归零
	private int pos = 0;
	//定义一个计数器用于记录缓冲区中的数据个数,当该数据减到0;
	//就从源中继续获取数据到缓冲区中.
	private int count = 0;
	MyBufferedReader(Reader r){
		this.r = r;
	}
	//该方法从缓冲区中一次取一个字符
	public int myRead() throws IOException{
		//从源中获取一批数据到缓冲区中,需要先做判断,只有计数器为0时,才需要
		//从源中获取数据.
		if(count == 0){
			count = r.read(buf);
			//每次获取数据到缓冲区后,角标归零
			pos = 0;
		}
		if(count<0)
			return -1;
		
		char ch = buf[pos];
		pos++;
		count--;
		return ch;		
	}
	public String myReadLine() throws IOException{
		StringBuilder sb = new StringBuilder();
		int ch = 0;
		while((ch=myRead())!=-1){
			if(ch=='\r')
				continue;
			if(ch=='\n')
				return sb.toString();
			//从缓冲区读取到的字符,存储到缓冲行的缓冲区中
			sb.append((char)ch);
		}
		if(sb.length()!=0){
			return sb.toString();
		}
		return null;
	}
	public void myClose() throws IOException{
		r.close();
	}

}

public class _13BufferTest {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("IoDemo.txt");
		MyBufferedReader mbr = new MyBufferedReader(fr);
		String line = null;
		while((line=mbr.myReadLine())!=null){
			System.out.println(line);
		}
		mbr.myClose();
	}
}

输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~

package cn.fuxi._06io;
/**
 * IO流常用基类-字节流
 * 基本操作与字符流类相同.但它不仅可以操作字符,还可以操作其他媒体文件.
 */
import java.io.*;
public class _14FileOutputStream {
	public static void main(String[] args) throws IOException {
		demo_write();
	}
	public static void demo_write() throws IOException{
		//1.创建字节流输出对象,用于操作文件
		FileOutputStream fos = new FileOutputStream("IoDemo.txt",true);
		//2.写数据,直接写入到了目的地中
		fos.write("ssdlajs".getBytes());
		//3.关闭资源~
		fos.close();
	}

}
输出结果:
黑马程序员——Java基础——IO流(一)_第4张图片

package cn.fuxi._06io;
/**
 * FileInputStream
 */
import java.io.*;
public class _15FileInputStream {
	public static void main(String[] args) throws IOException{
		demoRead1();
		demoRead2();
		demoRead3();
	}
	//读取方式一:全部一次性用数组读取
	public static void demoRead1() throws IOException{
		//创建一个读取流对象,和指定文件关联
		FileInputStream fis = new FileInputStream("IoDemo.txt");
		//打印字符字节大小,不过要少用,文件太大,可能内存溢出
		byte[] buf = new byte[fis.available()];
		fis.read(buf);
		System.out.println(new String(buf));
		fis.close();
	}
	//方式二:推荐使用数组缓冲
	public static void demoRead2() throws IOException{
		FileInputStream fis = new FileInputStream("IoDemo.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 demoRead3() throws IOException{
		FileInputStream fis = new FileInputStream("IoDemo.txt");
		InputStreamReader isr = new InputStreamReader(fis);
		int ch = 0;
		while((ch = isr.read())!=-1){
			System.out.print((char)ch);
		}
		fis.close();	
	}
}
/*
 * FileOutputStream,FileInputStream的flush方法为空,没有任何实现,调用没有意义.
 * 字节流的缓冲区,同样是提高字节流的读写效率.
 */
输出结果:
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs
我不会告诉你我的马甲名字其实就是传说中的传奇查
我传奇查有100种方法让你在IT界混不下去!糖宝~啦啦啦~种太阳~ssdlajs

package cn.fuxi._06io;
/**
 * 练习:
 * 		通过几种方式对MP3经行拷贝,比较它们的效率.
 */
import java.io.*;
public class _16Mp3CpoyTest {
	public static void main(String[] args) throws IOException{
		method_Int();
		method_Array();
	}
	public static void method_Int() throws IOException{
		long l1 =System.currentTimeMillis();
		FileInputStream fis = new FileInputStream("澤野弘之 - aLIEz (instrumental).flac");
		FileOutputStream fos = new FileOutputStream("Copy - aliez.flac");
		int ch = 0;
		while((ch = fis.read())!=-1){
			fos.write(ch);
		}
		fos.close();
		fis.close();
		long l2 = System.currentTimeMillis();
		System.out.println(l2-l1);
	}
	public static void method_Array() throws IOException{
		long l1 = System.currentTimeMillis();
		FileInputStream fis = new FileInputStream("澤野弘之 - aLIEz (instrumental).flac");
		FileOutputStream fos = new FileOutputStream("Copy2 - aliez.flac");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = fis.read(buf))!=-1){
			fos.write(buf,0,len);
		}
		fos.close();
		fis.close();
		long l2 = System.currentTimeMillis();
		System.out.println(l2-l1);
	}
}
输出结果:
162982
277






你可能感兴趣的:(Java学习笔记,黑马程序员,java,io流)