Java中I/O使用入门详解(1)

#Java中I/O使用入门详解(1)
本文介绍了 FileInputStream,FileOutputStream等常用输入输出流的使用方式,(来自于以前的学习笔记,现整理出来和大家分享).
通俗易懂,老少皆宜O(∩_∩)O~

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * IO的分类:
 * 		流向:
 * 			输入流:读取数据
 * 			输出流:写入数据
 * 		数据类型:
 * 			字节流
 * 				字节输入流	读取数据	InoutStream
 * 				字节输出流	写入数据	OutputStream
 * 			字符流
 * 				字符输入流	读取数据	Reader
 * 				字符输出流	写入数据	Writer
 * 
 * 		注意:一般在探讨IO流,不说的话是按数据类型来说的
 * 
 * 需求:往一个文本文件中写入一句话:"hello,IO".
 * 
 * 分析:
 * 		A:这个最好用字符流实现,这里用字节流
 * 		B:由于我是想往文件中写一句话,所以我们用字节输出流
 * 通过上面的分析后我们知道要使用OutputStream
 * 但是通过查看API,我们发现该流对象是一个抽象类,不能实例化
 * 所以我们要找一个具体的子类,这个时候很简单,实际上,我们是要往文件中写东西
 * 文件单词:File
 * 然后用的是字节流,连起来就是FileOutputStream
 * 注意:每种基类的子类都是以父类名作为后缀名
 * 
 * 查看FileOutputStream构造方法
 * 		FileOutputStream(File file)
 * 		FileOutputStream(String name)
 */
public class FileOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		//创建字节流输出对象
		//FileOutputStream(File file)
//		File file= new File("fos.txt");
//		FileOutputStream fos=new FileOutputStream(file);
		FileOutputStream fos=new FileOutputStream("fos.txt");
		/*
		 * 创建字节输出流对象做了几件事情
		 * 1:调用系统功能去创建文件
		 * 2:创建fos对象
		 * 3:把fos对象指向这个文件
		 */
		
		//写数据
		fos.write("hello,IO".getBytes());
		
		//释放资源
		fos.close();
		/*
		 * 为什么一定要close呢?
		 * A:关闭流对象,使流对象变成垃圾,以免后面别人接着写
		 * B:通知系统去释放相关的资源
		 */
	}
}

##1.FileOutputStream

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 字节输出流操作步骤
 * A:创建字节输出流对象
 * B:调用write()方法
 * C:释放资源
 * 
 * public void write(int b);写一个字节
 * public void write(byte[] b);写一个字节数组
 *  public void write(byte[] b,int Off,int len);写一个字节数组的一部分
 */
public class FileOutputStreaDemo2 {
	public static void main(String[] args) throws IOException {
		//创建字节流输出流对象
		//OutputStream os=new FileOutputStream("fos2.txt);//这是多态
		FileOutputStream fos=new FileOutputStream("fox2.txt");
		
		//调用write()方法
		fos.write(97);//97----底层是二进制数组----通过记事本打开-----找97对应的字符值----a
		
		//public void write (byte[] b):写一个字节流数组
		byte[] bys={97,98,99,100,101};
		fos.write(bys);
		
		//public void write(byte[] b,int Off,int len);写一个字节数组的一部分
		fos.write(bys,1,3);
		fos.close();
	}
}

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 如何实现数据的换行?
 * 		为什么没有换行呢?因为只写了字节数据,并没有写入换行符号
 * 		如何实现换行?写入换行符号即可
 * 		刚才用"\n"我们看到有些文本文件打开是可以的,但用Windows自带却不行
 * 			原因:不同的系统对于换行符号识别是不一样的
 * 			windows:\r\n
 * 			linux:\n
 * 			Mac:\r
 * 
 * 		而一些高级写字本软件可识别任意的换行符的
 * 如何实现数据的追加写入?
 * 		用构造方法待第二个参数为true的情况即可
 */
public class FileOutputStreamDemo3 {
	public static void main(String[] args) throws IOException {
		//创建字符输出流
		//FileOutputStream fos=new FileOutputStream("fos3.txt");
		
		FileOutputStream fos=new FileOutputStream("fos3.txt",true);
		
		//写数据
		for(int i=0;i<10;i++){
			fos.write(("hello"+i).getBytes());
			fos.write("\n".getBytes());
		}
		fos.close();
	
	}
}
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 * 加入异常处理的字节输出流操作
 * 
 */
public class FileOutputStreamDemo4 {
	public static void main(String[] args) {
FileOutputStream fos=null;
		try {
			fos = new FileOutputStream("fos4.txt");
			fos.write("java".getBytes());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}finally{
			//如果fos不是null,才需要close()
			if(fos!=null){
				try {
					fos.close();
					} catch (IOException e) {	
						e.printStackTrace();
					}
				}
			}
	}
}

##2.FileInputStream

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 *字节输入流操作步骤
 *A:创建字节输入流对象
 *B:调用read()方法读取数据,并把它显示到控制台
 *C:释放数据
 * 
 * 读取数据的方式
 * A:int read();一次读取一个字节
 * B:int read(byte[] b);一次读取一个字节数组
 * 
 */
public class FileInputStreamDemo {
	public static void main(String[] args) throws IOException {
		//FileInputStream(String name);
		FileInputStream fis=new FileInputStream("fis.txt");
		
		//用int read();
		//第一次读取
//		int by=fis.read();
//		System.out.println(by);
//		System.out.println((char)by);
//		
//		//第二次读取
//				by=fis.read();
//				System.out.println(by);
//				System.out.println((char)by);
//		//第三次读取
//				by=fis.read();
//				System.out.println(by);
//				System.out.println((char)by);
		//我们发现代码的重复度很高,应该用循环改进		
		//而用循环,最麻烦的是如何控制循环的条件		
		//多测两次后发现,读取的结果为-1,说明已经读取到文件的末尾了		
				
		//循环改进
//		int by=fis.read();
//		while(by!=-1){
//			System.out.print((char)by);
//			by=fis.read();
//		}
		
		//最终版代码
		int by=0;
		//读取,赋值,判断
		while((by=fis.read())!=-1){
			System.out.println((char) by);
		}			
		//释放资源
		fis.close();
	}
}

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 一次读取一个字节数组
 * 返回值是读取字节的
 */
public class FileInputStreamDemo2 {
	public static void main(String[] args) throws IOException {
		//创建字节输入流对象
		FileInputStream fis=new FileInputStream("fis2.txt");
		
		//读取数据
		//定义一个字节数组
		//第一次读取
//		byte[] bys=new byte[5];
//		int len=fis.read(bys);
//		System.out.println(new String(bys,0,len));
//		
		
//		byte[] bys =new byte[20];
//		int len=0;
//		while((len=fis.read(bys))!=-1){
//			System.out.println(new String (bys,0,len));
//			//System.out.println(new String (bys)此做法有问题,千万要注意
//		}
			
		//最终版
		//数组的长度一般是1024或者1024的倍数
		byte[] bys=new byte[1024];
		int len=0;
		while((len=fis.read(bys))!=-1){
			System.out.println(new String (bys,0,len));
		}
		//释放资源
		fis.close();
	}
}

##3.一些文件复制应用的例子#

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

/*
 * 
 * 复制文本文件
 * 
 * 数据源:从哪里来
 * a.txt		读取数据 FileinputStream
 * b.txt		写数据 FileOutputStream
 * 目的地:到哪里去
 * b.txt
 * 
 * 这一次复制中文没有出现任何问题,为什么?
 * 上一次我们出现问题是由于我们把每次获取到一个字节数据,就把该字节数据转换为字符数据
 * 而这一次,却是通过IO流读取数据,你读取一个字节,我就写入一个字节,没有存在任何转换
 * 他会自己转换
 * 
 */
public class CopyFileDemo {
	public static void main(String[] args) throws IOException {
		//封装数据源
		FileInputStream fis=new FileInputStream("a.txt");
		//封装目的地
		FileOutputStream fos=new FileOutputStream("b.txt");
		
		int by=0;
		while((by=fis.read())!=-1){
			fos.write(by);
		}
		
		//释放资源(先关谁都行)
		fos.close();
		fis.close();
	}
}

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

/*
 * 
 * 复制文本文件
 * 
 * 数据源:从哪里来
 * 				c:\\a.txt		读取数据 FileinputStream		
 * 目的地:到哪里去
 * 				d:\\b.txt		写数据 FileOutputStream
 * 
*/
public class CopyFileDemo2 {
	public static void main(String[] args) throws IOException {
		//封装数据源
		FileInputStream fis=new FileInputStream("c:\\a.txt");
		//封装目的地
		FileOutputStream fos=new FileOutputStream("d:\\b.txt");
		
		//复制数据
		int by=0;
		while ((by=fis.read())!=-1){
			fos.write(by);
		}
		fis.close();
		fos.close();
	}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 需求:把e:\\a.jpg内容复制到当前项目下的aa.jpg中
 * 
 */
public class CopyImageDemo {
	public static void main(String[] args) throws IOException {
		//封装数据源
		FileInputStream fis=new FileInputStream("e:\\a.jpg");
		
		//封装目的地
		FileOutputStream fos =new FileOutputStream("aa.jpg");
		
		//复制数据
		int by=0;
		while((by=fis.read())!=-1){
			fos.write(by);
		}
		//释放资源
		fos.close();
		fis.close();
	}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 把D:\\a.txt内容复制到E:\\b.txt中
 */
public class CopyFileDemo {
	 public static void main(String[] args) throws IOException {
		//封装数据源
		FileInputStream fis=new FileInputStream("d:\\a.txt"); 
		
		//封装目的的
		FileOutputStream fos=new FileOutputStream("e:\\b.txt");
		
		//复制数据
		byte[] bys=new byte[1024];
		int len=0;
		while((len= fis.read(bys))!=-1){
			fos.write(bys,0,len);
		}
		//释放资源
		fis.close();
		fos.close();
	}
}

##4.BufferedOurtputStream与BufferedInputStream#

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 我们通过定义数据的方式的确比以前一个一个读取有效率得多,看来有一个缓冲区是很好的
 * 其实java开始设计时,就考虑了这个问题,就专门提供了缓冲区的字节类
 * 这种类被称为:缓冲区类(高效类)
 * 写数据:BufferedOutputStream
 * 读数据:BufferedInputStream
 * 
 * 构造方法可以指定缓冲区大小,但我们一般用不上,因为默认的缓冲区大小就够了
 * 
 * 为什么不传递一个具体的文件或文件路径,而是传送一个OutputStream对象呢?
 * 原因很简单,字节缓冲区仅仅提供缓冲区,为高效而设计的,但是呢,真正的读写操作还得靠基本的流对象
 * 
 */
public class BufferedOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		//BufferedOutputStream(OutputStream out);
//		FileOutputStream fos=new FileOutputStream("bos.txt");		
//		BufferedOutputStream bos=new BufferedOutputStream(fos);
		BufferedOutputStream bos=new BufferedOutputStream(
							new FileOutputStream("bos.txt"));
	
		//写数据
		bos.write("hello".getBytes());
		bos.close();
	}
}
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class BufferedInputStreamDemo {
	public static void main(String[] args) throws IOException {
		//BufferedInputStream(InputDtream in)
		BufferedInputStream bis=new BufferedInputStream(
				new FileInputStream("bos.txt"));
		
		//读数据
//		int by =0;
//		while((by=bis.read())!=-1){
//			System.out.println((char) by);
//		}
		
		byte[] bys=new byte[1024];
		int len =0;
		while ((len=bis.read(bys))!=-1){
			System.out.println(new String(bys,0,len));
		}
		
		bis.close();
	}
}

最后,我们来比较一下四种读写2方式的速度差异:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 把e:\\下的a.mp4复制到当前目录下的aa.mp4
 * 
 * 字节流四种方式复制文件
 * 基本字节流一次读写一个字节
 * 基本字节流一次读写一个字节数组
 * 高效字节流一次读写一个字节
 * 高效字节流一次读写一个字节数组
 * 
 */
public class CopyMp4Demo {
	public static void main(String[] args) throws IOException {
		long start=System.currentTimeMillis();
		//method1("e:\\a.mp4","copy1.mp4");共耗时:  81700ms
		//method2("e:\\a.mp4","copy2.mp4");共耗时:  326ms
		//method3("e:\\a.mp4","copy3.mp4");共耗时:  1899ms
		//method4("e:\\a.mp4","copy4.mp4");共耗时:  137ms
		long end=System.currentTimeMillis();
		System.out.println("共耗时:  "+(end-start)+"ms");
	}

	
	//基本字节流一次读写一个字节
	private static void method1(String srcString, String destString) throws IOException {
		FileInputStream fis=new FileInputStream(srcString);
		FileOutputStream fos=new FileOutputStream(destString);
		
		int by=0;
		while((by=fis.read())!=-1){
			fos.write(by);
		}
		fos.close();
		fis.close();		
	}
	

	//基本字节流一次读写一个字节数组
		private static void method2(String srcString, String destString) throws IOException {
			FileInputStream fis=new FileInputStream(srcString);
			FileOutputStream fos=new FileOutputStream(destString);
			
			byte[] bys=new byte[1024];
			int len=0;
			while((len=fis.read(bys))!=-1){
				fos.write(bys,0,len);
			}
			
			
			fos.close();
			fis.close();		
		}
		
		//高效字节流一次读写一个字节
		private static void method3(String srcString, String destString) throws IOException {
			BufferedInputStream bis=new BufferedInputStream(
					new FileInputStream(srcString));
			BufferedOutputStream bos=new BufferedOutputStream(
					new FileOutputStream(destString));
			
			int by=0;
			while((by=bis.read())!=-1){
				bos.write(by);
			}
			bos.close();
			bis.close();		
		}
			
		//高效字节流一次读写一个字节数组
		private static void method4(String srcString, String destString) throws IOException {
					BufferedInputStream bis=new BufferedInputStream(
							new FileInputStream(srcString));
					BufferedOutputStream bos=new BufferedOutputStream(
							new FileOutputStream(destString));
					
					byte[] bys=new byte[1024];
					int len=0;
					while((len=bis.read(bys))!=-1){
						bos.write(bys,0,len);
					}
					bos.close();
					bis.close();		
				}
}

##5.关于I/O使用的小结提纲#
###(1)用于在设备间数据传输的操作
###(2)分类: #
####A:流向
输入流 --> 读取数据
输出流 --> 写入数据
####B:数据类型
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流
a:如果我们没明确说明按照什么分,默认按照数据类型分
b:除非文件用Windows自带记事本打开我们能够读懂,才采用字符流,否则采用字节流
###(3)FilOutoutStream写出数据
####A:操作步骤
a:创建自己人输出流操作对象
b:调用Write()方法
c:释放资源
####B:代码体现:
FileOutputSream fos=new FileOutputStream(“fos.txt”);

		fos.write("hello".getBytes());
		
		fos.close();

####C:要注意问题?
a:创建字节输出流对象做了几件事情?
b:为啥要close()?
c:如何实现数据的换行?
d:如何实现数据的追加写入?
####(4)FIleInputStream读取数据
#####A:操作步骤
a:创建字节输入流对象
b:调用read()方法
c:释放资源
#####B:代码实现:
FileInputStream fis =new FileInputStream(“fos.txt”);

 		//方式一
 		int by=0;
 		while((by=fis.read()!=-1)){
 			System.out.print((char)by);
 		}	
 	
 		fis.close;
 		
 		//方式二
 		byte[] bys=new byte[1024];
 		int len=0;
 		while((len=fis.read(bys))!=-1){
 			System.out.print(new String(bys,0,len));
 		}
 		 	
 		fis.close;

###(5)案例:
A:复制文本文件
B:复制图片
C:复制视频
###(6)字节缓冲区流
A:BufferedOutputStream
B:BufferedIntputStream
###(7)例子:几种实现
A:复制文本文件
B:复制图片
C:复制视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值