黑马程序员java自学总结--IO

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

IO流

定义:
IO流用来处理设备之间的数据传输
java对数据的操作是通过流的方式
java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流和字符流
早期都是字节流,机器上都是字节。字符流的由来是因为可以在内部融合编码表。通用字节流,字符流基于字节流。

流按流向分为:输入流,输出流


IO流常用基类
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer。
注:由这四个类派生出来的子类名称都是以期父类名作为子类名的后缀。如
InputStream的子类FileInputStream,Reader的子类FileReader。
字符流的缓冲区
缓冲区的出现提高了对数据的读写效率
对应类
BufferedWriter;BufferedReader
缓冲区要结合流才可以使用

在流的基础上对流的功能进行了增强。

Reader:

	public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("demo2.txt");
			int c = 0;
			while((c=fr.read()) != -1){
				System.out.println((char)c);
			}					
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fr != null){
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}
注释:Reader接口提供了很多的实现,其中FileReader可以跟文件相关来操作,其中它的read方法一次读取一个字符。

读取字符的自定义缓冲区读取:

public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("demo2.txt");
		char [] buf = new char[1024];//相当于一个缓冲区
		int num = 0;
		while((num=fr.read(buf))!=-1)
		
		System.out.println("num=" + num +"___"+new String(buf,0,num));

我们这样可以增加效率,java给我们的缓冲区操作进行了优化,增加了一个BufferedReader类,它自带缓冲区

示例程序:

public static void main(String[] args) throws IOException {
		//创建一个读取流对象和文件相关联
		FileReader fr = new FileReader("buf.txt");
		BufferedReader br = new BufferedReader(fr);
		String s1 = null;
		while((s1=br.readLine())!=null){
			System.out.println(s1);
		}
		
		br.close();

练习:

读取一个.java文件,并打印在控制台上

public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("StringDemo.java");
			char [] buf = new char[1024];
			int num = 0;
			try {
				while((num=fr.read(buf)) != -1){
					System.out.print(new String(buf,0,num));
				}
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

	}


Writer:

 学习字符流的特点
 既然IO流是用于操作数据的
 那么数据的常见体现形式是:文件
 先以操作文件为主来演示
需求:在硬盘上,创建一个文件并写入一些文字数据
找到一个专门的操作文件的Writer的子类对象,FileWriter,后缀名是父类名,前缀是具体的功能


MyBufferedReader练习:
使用到的装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有的对象传入,基于已有的功能,提供加强功能
那么自定义的该类称为装饰类

特点:装饰类通常会通过构造方法接受被装饰的对象,并基于别装饰的对象的功能,提供增强的功能;装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,所以装饰类和被装饰类通常是都属于一个体系中。


File类
用来将文件或者文件夹封装成对象
方便对文件与文件夹的属性信息进行操作
File对象可以作为参数传递给流的构造函数
了解File类中的常用方法

注:流只能操作数据,要操作文件信息就要File类

public static void main(String[] args) throws IOException {
		// 创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件
		//而且该文件会被创建到指定的目录下,如果该目录下已有同名文件,将被覆盖
		//其实该步就是在明确要存放的目的地
		FileWriter fw = new FileWriter("demo.txt");
		//调用write方法写入到流里面去了,没到目的地中,
		fw.write("hello ylm");
		//通过flush方法把数据刷到目的地去。
		fw.flush();//
		fw.write("how are you");
		fw.flush();//流资源没有关闭,通过flush刷到目的地
		
		fw.close();//关闭流资源,会刷新一次内部的缓冲中的数据
		
IO异常的处理方式:

public static void main(String[] args) {
		FileWriter fw = null;
		try {
			fw = new FileWriter("demo2.txt");
			fw.write("adfsdf");
			fw.close();
		} catch (IOException e) {
			System.out.println(e.toString());
		}finally{
			try {
				if(fw != null)//要为空判断,若是创建不成功fw为空。
				fw.close();
			} catch (IOException e) {
				System.out.println("关闭异常");
			}
		}

Writer同样也有缓冲区操作的类BufferedWriter:

public static void main(String[] args) throws IOException {
		//创建一个字符写入流对象
		FileWriter fw = new FileWriter("buf.txt");
		BufferedWriter bufw = new BufferedWriter(fw);
		bufw.write("fasdf");
		//记住,只要用到缓冲区,就要记得刷新
		bufw.flush();
		//其实关闭缓冲区,就是在关闭缓冲区中的流对象
		bufw.close();
	}

缓冲区的出现是为了提高流的操作效率而出现的
所以在创建缓冲区之前,必须要先有流对象

示例程序:

public static void main(String[] args) {
		FileWriter fw = null;
		
		try {
			fw = new FileWriter("bufwriter.txt");
			BufferedWriter bw = new BufferedWriter(fw);
			for (int i = 0; i < 5; i++) {
				bw.write("sfsdf" + i);
				bw.newLine();//提供的一个跨平台的换行符
				bw.flush();
			}
			bw.close();//实际关闭的是fw的close方法。
		} catch (IOException e) {
			e.printStackTrace();
		}

在原有文件的后面续写数据:由于之前我们的写入流关联的文件是直接创建,硬盘有的话也会直接覆盖。

public static void main(String[] args) {
		FileWriter fw = null;
		try {
			fw = new FileWriter("demo2.txt",true);
			fw.write("nihao\r\nhahha");//回车符
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

练习:

 将c盘一个文件复制到D盘 复制的原理:其实就是将c盘下的文件数据存储到d盘的一个文件中 定义读取流和c盘文件管理
通过不断的读写完成数据的存储 关闭资源

	// 方法一:从c盘读取一个字符,就往d盘写一个字符
	public static void copy_1() {
		FileWriter fw = null;
		FileReader fr = null;

		try {
			// 创建目的地
			fw = new FileWriter("StringDemo_copy.txt", true);
			// 与已有的文件相关联
			fr = new FileReader("StringDemo.java");
			int c = 0;
			while ((c = fr.read()) != -1) {
				
				fw.write((char) c);
			}
			System.out.println();

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fw != null)
					fw.close();
			} catch (IOException e1) {

				e1.printStackTrace();
			}
			try {
				if (fr != null)
					fr.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
	}

	// 方法二:读取到一个字符数组缓冲区。再写到另一个文件中
	public static void copy_2() {
		FileReader fr = null;
		FileWriter fw = null;
		int ch = 0;
		char[] buf = new char[1024];
		try {
			fr = new FileReader("StringDemo.java");
			fw = new FileWriter("copy_2.txt", true);
			while ((ch = fr.read(buf)) != -1) {
				fw.write(buf,0,ch);
			}
		} catch (IOException e) {

			e.printStackTrace();
		} finally {
			try {
				if (fr != null)
					fr.close();
			} catch (IOException e1) {

				e1.printStackTrace();
			}
			try {
				if (fw != null)
					fw.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
	}

通过缓冲区复制一个.java 文件:

public static void main(String[] args) {
		BufferedReader bufr = null;
		BufferedWriter bufw = null;
		FileWriter fw = null;
		FileReader fr = null;
		String line = null;
		try {
			fw = new FileWriter("bufferCopy.txt");
			fr = new FileReader("StringDemo.java");
			bufr = new BufferedReader(fr);
			bufw = new BufferedWriter(fw);
			while((line=bufr.readLine()) != null){
				bufw.write(line);//注意这里要换行
				bufw.newLine();
				bufw.flush();
			}
		} catch (IOException e1) {
			e1.printStackTrace();
		}finally{
			try {
				if(bufr != null)
				bufr.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			try {
				if(bufw != null)
				bufw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
	}

InputStream

字节流读入类

OutputStream

字节流写出类

注:对字节流的读写顺序和字符流一样,字节流针对的字节数据,字符流是针对纯文本数据,那些字符是我们可以看懂的,字节流的数据是二进制数据,是存在机器里面的二进制形式。同样字节流也有自己的缓冲区类BufferedInputStream,BufferedOutputStream

练习:将一个图片文件中数据存储到另一个文件中。复制文件。

public static void copy_1()
	{
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\0.jpg"));
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\test\\1.jpg"));
			int len = 0;
			while((len = bis.read()) != -1){
				bos.write(len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
Properties类:


 想要将info.txt中的健值数据存到集合中
1.用一个流和Info.txt文件关联
2.读取一行数据,将该行数据用“=”进行切割
3.等号左边作为健,右边作为值,存到Properties中

public static void loadDemo() throws IOException{
		FileInputStream fis = new FileInputStream("info.txt");
		FileOutputStream fos = new FileOutputStream("info.txt");
		Properties p = new Properties();
		p.load(fis);
		//p.setProperty("lisi", "5");
		//p.store(fos, "haha");
		p.list(System.out);
		//fis.close();
		//fos.close();
	}
	public static void getProperties() throws IOException{
		BufferedReader br = new BufferedReader(new FileReader("info.txt"));
		String line = null;
		Properties p = new Properties();
		while((line=br.readLine()) != null){
			String[] arr = line.split("=");
			System.out.println();
			p.setProperty(arr[0],arr[1]);
		}
		System.out.println(p);
	}
	public static void setAndGet(){
		Properties p = new Properties();
		p.setProperty("zhangsan", "20");
		p.setProperty("lisi", "20");
		System.out.println(p);
	}

PrintStream

字符文件输出类:

public static void main(String[] args) throws IOException {
		PrintStream ps = new PrintStream(System.out);
		BufferedReader bw = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		while((line=bw.readLine()) != null){
			if(line.equals("over"))
				break;
			ps.println(line.toUpperCase());
			ps.flush();
		}
		ps.close();
		bw.close();
	}

PrintWriter

public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter p = null;
		try {
			p = new PrintWriter(new FileWriter("d:\\test\\printWriterDemo.txt"));
			String line = null;
			while((line=br.readLine()) != null) 
			{
				if("over".equals(line))
					break;
				p.println(line.toUpperCase());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			p.close();
			try {
				if(br != null)
				br.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

练习:将错误信息存储到到硬盘文件中

public static void main(String[] args) {
		try {
			int[] arr = new int[2];
			System.out.println(arr[5]);
		} catch (Exception e) {	
			try {
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss");
				String s = sdf.format(date);
				PrintStream p = new PrintStream("d:\\test\\error.txt");
				p.println(s);
				System.setOut(p);
			} catch (IOException e1) {
				throw new RuntimeException("日志文件创建失败");
			}
			e.printStackTrace(System.out);
		}
	}


File类常见方法
1.创建
  boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false
和输出流不一样,输出流对象一建立创建文件,而且文件已经存在,会覆盖
  2.删除
 void deleteOnExit();//当程序结束时删除,即时出现异常,也可以删除
  3.判断
  /boolean exists();//文件是否存在
  boolean mkdir()//创建文件夹,这个函数只可以创建一级目录
 boolean mkdirs();//可以创建多级目录
  boolean isDirectory;//是否是目录
 boolean isFile;//是否是文件
/4.获取信息
 getName();
 getPath();//获取封装的路径
  getParent();//该方法返回的是绝对路径的父目录,如果获取的是相对路径返回为null
  如何相对路径中有上一层目录,则返回父目录
 getAbsolutePath();//获取绝对的路径

private static void method_3() {
		File f = new File("StringDemo2.java");
		//在创建文件对象是否是文件或者目录是,必须要先判断该文件对象封装的内容是否存在
		try {
			f.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//syso(f.i)
		
	}

	//删除文件
	public static void method_2(){
		File f = new File("file.txt");
		syso("delete:" + f.delete());
		syso(f);
	}
	//创建文件
	public static void method_1(){
		File f = new File("file.txt");
		try {
			syso("create:" + f.createNewFile());
			syso(f);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//创建File对象
	public static void consMethod(){
		File f = new File("a.txt");
		File f2 = new File("c:\\abc","b.txt");
		File f3 = new File("c:" + File.separator + "d"+ File.separator + "abc.txt");
		syso(f);
		syso(f2);
		syso(f3);
	}
	public static void syso(Object obj){
		System.out.println(obj);
	}
}

练习:遍历目录

public static void showDir(File str,int level){
		System.out.println(getLevel(level)+str.getName());
		level++;
		File [] fileList = str.listFiles();
			for(int x = 0; x < fileList.length; x++) {
				if(fileList[x].isDirectory())
					showDir(fileList[x],level);
				else 
					System.out.println(fileList[x].getName());
			}	
	}
练习

.对指定的目录进行递归获取递归过程所有的java文件的路径.将这些路径存储到集合中将集合中的数据写入到一个文件中

public static void main(String[] args) {
		List<File> list = new ArrayList<File>();
		File f = new File("c:\\");
		fileToList(f,list);
		System.out.println(list.size());

	}

	public static void listToFile(List<File> list,File f) throws IOException{
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		for(File file:list){
			bw.write(file.getAbsolutePath());
			bw.newLine();
			bw.flush();
		}
		bw.close();
	}
	public static void fileToList(File dir,List<File> list){
		File[] files = dir.listFiles();
		for(File f:files){
			if(f.isDirectory()){
				fileToList(f,list);
			}else{
				if(f.getName().endsWith(".java"))
				list.add(f);
			}
		}
	}

编码表的由来:

计算机只能识别二进制数据,早期由来是电信号
为了方便应用计算机,让它可以识别各个国家的文字
就将各个国家的文字用数字来表示,并一一对应,形成一张表
这就是编码表
常见的编码表:
ASCII:美国标准信息交换吗
用一个字节的7位可以表示
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示
GB2312:中国的中文编码表
GBK:中国的中文编码表升级,融合了更多的中文文字符号
Unicode:国际标准码,融合了多种文字
所有文字都用两个字节来表示,java语言使用的就是Unicode
UTF-8:最多用三个字节来表示一个字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值