黑马程序员——IO流(二)内存操作流、打印流、标准输入输出流、序列流、Properties类

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

内存操作流的概述和讲解

源 FileIInputStream  FileReader它们的源就是文件 

目的地:FileOutputStream FileWriter它们的目的地就是文件。

 

BufferedInputStream 是输入流,它的源是  InputStream.

BufferedOutputStream是输出流 它的目的地 OutputStream.  

 

对于内存操作流,它们的源与目的地就是内存。

简单说,它是数据是从内存中读取来的,写入的目的地也是内存。

 

一共有三对

ByteArrayInputStream   ByteArrayOutputStream   对byte[]操作

CharArrayReader    CharArrayWriter  char[]操作

StringReader        StringWriter   String操作

 

介绍ByteArrayOutputStream

它的底层是一个byte[]数组,这个流是一个输出流,简单说,它写入的数据就写入到了底层的byte[]中。我们可以使用toByteArray()方法来获取底层写入的数据.

package cn.itcast.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class ByteArrayDemo {

	public static void main(String[] args) throws IOException {
		// 通过ByteArrayOutputStream来完成数据写入内存,并将写入的数据获取到.
		// 1.创建ByteArrayOutputStream
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		// 2.写入数据
		baos.write("hello world".getBytes()); // 将数据写入到底层的byte[]中。

		// 3.获取底层的byte[]
		byte[] b = baos.toByteArray();

		// baos.close(); //对于这个流来说,它操作的就是内存,所以不需要关闭.
		
		
		//通过ByteArrayInputStream来获取内存中的数据
		ByteArrayInputStream bais=new ByteArrayInputStream(b); //从b中读取数据
		
		int code=-1;
		while((code=bais.read())!=-1){
			System.out.print((char)code);
		}
	}
}

打印流的概述和特点

对于我们要学的打印流它只有输出。

我们学习的打印流有两个

PrintWriter  字符打印流

PrintStream  字节打印流

问题:PrintWriter打印流的目的地是哪?

1. 可以是文件

2. 可以是另一个字节输出流

3. 可以是另一个字符输出流

 

特点总结:

1. 只能输出,也就是说只有目的地

2. 它可以自动刷新,需要设置

3. 它可以操作文件或其它的流

4. 可以操作所有数据类型.

package cn.itcast.io;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterDemo1 {

	public static void main(String[] args) throws IOException {

		demo2();
	}

	// 使用PrintWriter来完成向文件中输出操作
	public static void demo1() throws FileNotFoundException {
		// 1.创建一个PrintWriter
		PrintWriter pw = new PrintWriter("a.txt");

		// 2.输出(打印)

		pw.write("hello");
		pw.write("world");
		pw.write("good");

		// 3.关闭
		pw.close();
	}

	// 我们使用BufferedWriter来对PrintWriter包装
	public static void demo2() throws IOException {
		// 1.创建一个PrintWriter
		PrintWriter pw = new PrintWriter("a.txt");

		BufferedWriter bw = new BufferedWriter(pw); // 将PrintWriter使用BufferedWriter来包装
		// 2.输出(打印)

		bw.write("hello");
		bw.newLine();
		bw.write("world");
		bw.newLine();
		bw.write("good");

		// 3.关闭
		bw.close();
	}
}

PrintWriter实现自动刷新和换行

对于PrintWriter来说,它的自动刷新与换行只有在设置了autoflush=true,并且调用println(xxx)方法才可以实现。


问题:PrintWriter中提供了write方法也提供了print方法,有什么区别?

write方法参数如果是int类型,代表的是要写的字符的码值。

print方法它的底层都是调用了write(String)这个方法,也就是说,所有的数据全是原样写入。

打印流改进复制文本文件案例

package cn.itcast.io;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

//使用PrintWriter来改进文件复制操作
public class PrintWriterDemo2 {

	public static void main(String[] args) throws IOException {

		// 1.创建一个读取a.txt文件的输入流
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw = new PrintWriter(new FileWriter("aa.txt"), true);

		// 2.复制
		String line = null;
		while ((line = br.readLine()) != null) {
			pw.println(line); // 底层就是 write(line) newLine() flush
		}

		// 3.关闭
		br.close();
		pw.close();
	}
}

标准输入输出流概述和输出语句的本质

标准输入设备:键盘

标准输出设备:显示器

 

标准输入流:从键盘读取信息。

标准输出流:向屏幕输出信息

 

标准输出流是:System.out

标准输入流是:System.in

package cn.itcast.io;

import java.io.IOException;
import java.io.InputStream;

//使用System.in来从键盘读取数据
public class SystemINAndOutDemo2 {

	public static void main(String[] args) throws IOException {
		InputStream is = System.in;
		// 通过System.in获取的是一个InputStream,但是InputStream是abstract类
		// 也就是说,其实返回的真实类型应该是InputStream的一个子类.

		// 一次读取一个字节
		//int code = is.read(); //read方法是一种阻塞式的方法,如果没有读到信息会等待,只有读到了信息才会向下执行.
		//System.out.println((char) code);
	
		//一次读取多个信息
		byte[] b=new byte[5];
		int len=is.read(b); //一次最多可以读取5个字节
		
		System.out.println(new String(b,0,len));
	}
}

三种方式实现键盘录入

1. Scanner sc=new Scanner(System.in);

这种方式只有在jdk1.5后才可以使用.

 

2. 使用io流来操作

System.in可以读取数据.

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

System.in 是一个从键盘读信息的字节输入流

我们使用InputStreamReaderSystem.in包装,就可以一次读取一个字符或多个字符。

在使用BufferedReader来包装一次,就可以一次读取一行信息.

 

3. 是使用命令行参数

就是利用了main方法的参数

输出语句用字符缓冲流改进

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

序列化和反序列化流的概述和使用

我们说的序列化流也是对象流ObjectInputStream   ObjectOutputStream

 

对于我们在网络或文件中要传输的对象,它们必须是可序列化的。

 

ObjectOutputStream可以将一个对象写入到网络或文件

ObjectInputStream可以从网络或文件中读取一个对象。

 

问题:为什么要对对象进行读写操作?

一个对象需要被其它人使用,我们就可以将对象直接通过流传递。

只有可以被序列化的对象数据才可以存储到文件中或在网络中传递。

 

问题:怎样可以标识对象是序列化的?

只需要让我们类实现 java.io.Serializable接口就可以。

 

注意:如果通过对象流将一个对象写入到文件或在网络中传输,就要求,对象必须是可序列化的。


package cn.itcast.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import cn.itcast.Student;

//使用ObjectInputStream与ObjectOutputStream流来完成对象存储与从文件中读取对象操作.

public class ObjectStreamDemo1 {

	public static void main(String[] args) throws FileNotFoundException,
			IOException, ClassNotFoundException {
		//writeObject();

		 readObject();
	}

	public static void readObject() throws IOException, ClassNotFoundException {
		// 1.创建对象流
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				"obj.txt"));// 从obj.txt文件读取对象

		// 2.从文件中读取一个对象
		Object obj = ois.readObject();
		// 3.关闭
		ois.close();

		System.out.println(obj);
	}

	// 1.写对象
	public static void writeObject() throws IOException {
		// 1.创建对象流

		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				"obj.txt"));

		// 2.向文件中写入一个对象
		Student s = new Student();
		s.setAge(20);
		s.setId(1);
		s.setName("tom");
		oos.writeObject(s);

		// 3.关闭
		oos.close();
	}
}

Properties的概述和作为Map集合的使用

在开发中,我们说的Properties它其实指的是一个配置文件。

 这种配置文件的特点是键值对映射

而我们在jdk中有一个Properties类,它其实就是一个map集合。

关于java.util.Properties类的用法:

就像Map一样就可以

Properties的特殊功能使用

Properties这个类虽然是一个Map,但是它没有泛型,原因,是它的keyvalue都是String类型。

 

我们真正在使用Properties方法是一般不使用put get keyset这样的方法,我们一般使用这个类中提供的一些特殊的方法:

String getProperty(String key) --------相当于map中的get方法。

Object setProperty(String key,Stirng value)---相当于map中的put方法.

public Set<String> stringPropertyNames()---相当于map中的keySet方法

package cn.itcast.prop;
import java.util.Properties;
//	 String getProperty(String key) --------相当于map中的get方法。
//Object setProperty(String key,Stirng value)---相当于map中的put方法.
//public Set<String> stringPropertyNames()---相当于map中的keySet方法

public class PropertiesDemo2 {

	public static void main(String[] args) {
		// 创建一个Properties对象
		Properties p = new Properties();

		// 存储数据 
		p.setProperty("username", "tom"); //put
		p.setProperty("password", "123");
		
		//3.遍历
	
		for(String name:p.stringPropertyNames()){  //keySet
			System.out.println(name+"  "+p.getProperty(name));  //get()
		}
	}
}

Propertiesloadstor e list功能 

我们的Properties它可以与io流一起使用

 

load----它是从properties文件中将数据直接封装到Properties对象中.(读操作)

list---它是将Properties对象中的数据直接写入到properties文件中(写操作)

store方法是用于修改数据.

package cn.itcast.prop;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;

//演示Properties类中的 list  load  store方法
public class PropertiesDemo3 {

	public static void main(String[] args) throws Exception {

		// listDemo();

		// loadDemo();

		storeDemo();
	}

	// store方法
	public static void storeDemo() throws IOException {
		// 创建一个Properties对象
		Properties p = new Properties();

		p.setProperty("username", "james");
		p.setProperty("pasword", "123");

		FileWriter fw = new FileWriter("src/message.properties");
		p.store(fw, null);
		fw.flush();

		fw.close();
	}

	// load方法
	public static void loadDemo() throws IOException {
		// 创建一个Properties对象
		Properties p = new Properties();

		FileReader fr = new FileReader("src/message.properties");

		p.load(fr);

		fr.close();

		// 遍历Properties
		// for (String name : p.stringPropertyNames()) {
		// System.out.println(name + "  " + p.getProperty(name));
		// }

		System.out.println(p.getProperty("username"));

	}

	// list
	public static void listDemo() throws FileNotFoundException {
		// 创建一个Properties对象
		Properties p = new Properties();

		// 存储数据
		p.setProperty("username", "tom");
		p.setProperty("password", "123");

		// list方法参数可以是 PrintStream PrintWriter

		PrintWriter pw = new PrintWriter("src/message.properties"); // 向文件写入数据

		p.list(pw);

		pw.close();
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值