IO——字节流与字符流

字节流

File类是描述文件和文件夹的,并且其中定义的方法都是围绕文件和文件夹的操作展开的。

但是File类有缺陷,它无法去获取一个文件中的数据。

如果我们在程序中要读取文件中存放的具体的数据,或者给文件中写数据,这时必须使用Java中提供的另外一套机制来读取,

这套机制就是IO流技术。I: InputStream ; O:OutputStream

InputStream 

fileInputStream是inputStream常用子类。

fileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等.

常用的构造方法有:

FileInputStream(File file);FileInputStream( String path )

常用的方法有:

read( ); read(byte[] b);read(byte[] b,int off,int len):底层读取字节数据

close( ):关闭流,在使用完成之后一定要关闭流

两种read()方法的用法:

		FileInputStream fis = new FileInputStream("D:\\KJ-12\\Eclipse\\Demo\\hello.txt");
		int ch = 0;
		while((ch = fis.read())!=-1)
		{
			System.out.print((char)ch);
		}
		System.out.println();
		fis.close();
		FileInputStream fis1 = new FileInputStream("D:\\KJ-12\\Eclipse\\Demo\\hello.txt");
		byte[] b = new byte[8];
		int len = 0;
		while((len = fis1.read(b))!=-1)
		{
			System.out.println(len);
		}
		for(int i=0;i<b.length;i++)
		{
			System.out.print((char)b[i]);
		}
		fis1.close();

OutputStream

在OutputStream类下有直接的子类FileOutputStream:

FileOutputStream:是专门用于把程序中的数据写到指定的文件中的输出流对象,这个流主要是用来写字节数据的。

FileOutputStream的构造方法:

FileOutputStream(File file)在创建输出流对象的时候,指定一个文件对象,用于把数据写到指定的这个文件中

FileOutputStream(String  pathName) 在创建输出流对象的时候,把这个字符串当前一个具体的文件位置,然后把数据写到这个文件中

在使用输出流的时候,如果指定的文件不存在,会自动创建这个文件对象,如果文件存在,会创建一个新的把原来的文件覆盖掉。

注意:

前面两个构造方法如果指定的文件不存在,会自动创建这个文件对象,如果文件存在,会创建一个新的把原来的文件覆盖掉。

第三个构造方法写数据时,当文件不存在同样会新建一个文件,如果文件存在了,第二个参数表示是否追加,false表示不追加(默认),和其他的两个构造方法结果一致,为true时,表示追加,在原来内容的基础上新增新的内容。

常用方法:

write(int b); 把字节数据直接写到持久设备上

write( byte[] buf ); 把字节数组中的数据写到持久设备上。

write( byte[] buf , int off , int len ) 把buf字节数组中的数据从off下标开始共计写出len个字节数据

close() ; 关闭Java程序和外围设备直接的连接通道。

	FileInputStream fis = new FileInputStream("D:\\KJ-12\\Eclipse\\Demo\\hello.txt");
	byte[] b = new byte[8];
	fis.read(b);
	String name = "D:\\KJ-12\\Eclipse\\Demo\\world.txt";
	FileOutputStream fis1 = new FileOutputStream(name,true);
	fis1.write(b);
	fis.close();
	fis1.close();

字符流

Java给我们提供专门用于操作字符数据的流对象

字符输入流:Reader         

字符输出流:Writer

Reader

用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。

常用方法:

int read( ):执行一次,会得到一个字符数据,如果读取到文件末尾,返回的-1

int read(char[] c):执行一次,会从底层读取多个字符数据,存储在字符数组中,返回本次读取的字符数据个数,

如果读取到文件末位,返回-1

read(char[] c,int off,int len),将读取到的数据存储在数组中,从off开始,到len结束

void close( );

子类InputStreamReader常用的构造方法,它又称为转换流

InputStreamReader(InputStream in)

InputStreamReader(InputStream in,String charsetName)

FileReader类是InputStreamReader的子类

FileReader(File file)

FileReader(String name)

Writer

Writer类常用方法

write(String str) : 写一个字符串

write(String str,int off,int len): cbuf中的字符数据从off开始,共计写len

void close(): 关闭流

void flush() : 刷新

子类OutputStreamWriter常用的构造方法

OutputStreamWriter(OutputStream out)

OutputStreamWriter(OutputStream out, String charsetName)

FileWriter类是OutputStreamWriter的子类

FileWriter (File file)

FileWriter (String name)

	File file = new File("D:\\KJ-12\\Eclipse\\Demo\\world.txt");
	FileReader fr = new FileReader(file);
	int read = fr.read();
	System.out.println(read);
	System.out.println((char)read);
	FileWriter fw = new FileWriter(file,true);
	String s = "三年之期已到,叶辰回来了";
	fw.write(s);
	fw.flush();
	System.out.println("over");

注意:

用字符输出流写出数据的时候:

1、其实数据不直接写到文件中,而是把字节数据存储在缓冲区中。如果这时字符输出流的缓冲区没有写满,或者我们没有调用flush方法,或没有关闭流对象,在程序结束之前,数据依然在缓冲区中,不会被写到文件中。所以要求,在关闭流之前一定要做刷新操作。

2、字符输出流(FileWriter)关联的文件如果不存在,会在指定的位置创建,如果文件存在,在创建流对象的时候,没有指定的true值,这时会创建新的文件覆盖原来的文件。

flush和close什么区别

flush是把缓冲区的数据刷出到文件中,没有关闭流和文件之间的关联,在刷新之后,依然可以使用流对象继续给文件中写数据。

close方法在关闭流之前会先调用flush把缓冲区中的数据写底层文件中,然后把流和文件的关联关系断开。

一旦调用的close方法,流就已经被关闭了,就无法在使用当前这个流对象写数据。

DataInputStream

在IO包中提供了两个与平台无关的数据操作流

数据输出流:DataOutputStream

数据输入流:DataInputStream

其使用方法和字节流类似。

DataInputStream类

FilterInputStream的子类

与FileInputStream类结合使用读取二进制文件

构造方法:DataInputStream(InputStream in)

DataOutputStream类

FilterOutputStream的子类

与FileOutputStream类结合使用写二进制文件

构造方法:DataOutputStream(OutputStream out)

	//图片复制
	File file = new File("D:\\KJ-12\\Eclipse\\Demo\\bai.jpg");
	InputStream in = new FileInputStream(file);
	DataInputStream dis = new DataInputStream(in);
	
	File outFile = new File("D:\\KJ-12\\Eclipse\\Demo\\jin.jpg");
	OutputStream out = new FileOutputStream(outFile);
	DataOutputStream dos = new DataOutputStream(out);
	//刷出
	int i=0;
	while((i=dis.read())!=-1)
	{
		dos.write(i);
	}
	dos.flush();
	
	
	
	//先开后关
	dos.close();
	out.close();
	dis.close();
	in.close();
	

序列化和反序列化

序列化一个用于将对象状态转换为字节流的过程。需要使用对象输出流ObjectOutputStream。

简单的说:我们使用new关键字创建在内存中的对象,包括对象中的所有数据,持久性的保存到硬盘上,通常是文件中,

对象 ——> 文件

反序列化则是从特定的流中获取数据重新构建对象的过程 。需要使用对象输入流ObjectInputStream。

保存在文件中的对象通过反序列化的手段从新加载到内存中

文件——>对象

	//序列化
	Dog dog = new Dog(20,"dogdog");
	//NotSerializableException 未序列化异常
	//类实现序列化接口即可
	// 序列化:内存中的对象--->文件
	//反序列化:文件--->内存
	File file = new File("D:\\KJ-12\\Eclipse\\Demo\\hello.txt");
	OutputStream out = new FileOutputStream(file);
	ObjectOutputStream oos = new ObjectOutputStream(out);
	
	oos.writeObject(dog);
	
	oos.flush();
	oos.close();
	out.close();
	
	//反序列化
	File file1 = new File("D:\\KJ-12\\Eclipse\\Demo\\hello.txt");
	InputStream in = new FileInputStream(file1);
	ObjectInputStream ois = new ObjectInputStream(in);
	
	Object readObject = ois.readObject();
	//Object readObject2 = ois.readObject();
	
	System.out.println(readObject);
	//System.out.println(readObject2);

注意:

1:序列化和反序列化都是基于二进制流的,也就是说,信息转化为二进制存储在文件中之后,用文本编辑器打开查看的话,肯定是会出现乱码的。只有通过反序列化才能将存储的二进制读取出来,然后正常显示在控制台上。

2:如果一个对象要实现序列化的话,则这个类必须要实现一个序列化的接口

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值