黑马程序员---Java基础---IO流

-------  android培训 java培训 、期待与您交流! ----------

IO流

一、IO流

1.IO流的分类

按操作数据分为:字节流和字符流

按流的流向分为:输入流和输出流

2.IO流的作用

IO流是用来处理设备之间的数据传输的。java对数据的操作是通过流的方式,操作流的对象都在IO包中。

3.IO 流的抽象基类

第一,字节流的抽象基类:InputStream和OutputStream

第二,字符流的抽象基类:Reader和Writer

注意:

这四个基类派生的子类名称都是以父类名称作为子类名称的后缀。比如:InputStream的子类FileInputStream,Reader的子类FileReadr


二、字符流

1.字符流一般是操作纯文本文件的,一般用流FileReader和FileWriter

后缀名是父类名。 前缀名是该流对象的功能。

读取文件用FileReader,而写入文件则用流FileWriter

2.FileWriter流,即向文件中写入数据的流

例子:需求:在硬盘上,创建一个文件并写入一些文字数据。

找到一个专门用于操作文件的Writer子类对象。FileWriter

示例:

import java.io.*;
class  FileWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
		//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
		//其实该步就是在明确数据要存放的目的地。
		FileWriter fw = new FileWriter("demo.txt");
		//调用write方法,将字符串写入到流中。
		fw.write("abcde");
		//刷新流对象中的缓冲中的数据。
		//将数据刷到目的地中。
		//fw.flush();

		//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
		//将数据刷到目的地中。
		//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
		fw.close();
	}
}
若想对上面的文件接着继续写,在构造函数传递一个“true”,则写成:                                                            <span style="font-family: SimSun;">FileWriter fw = new FileWriter("demo.txt",true);                                                     </span><span style="font-family: SimSun;">fw.write("fghio");                                                                                    </span><span style="font-family: SimSun;">fw.close();</span>

3.FileReader即对已经存在的文件进行读取,读取有两种方式

第一种方式:用read()即一次读取一个字符,并返回int型,即字符相对应的ASCII码值

代码:

import java.io.*;
class  FileReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个文件读取流对象,和指定名称的文件相关联。
		//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
		FileReader fr = new FileReader("demo.txt");

		//调用读取流对象的read方法。
		//read():一次读一个字符。而且会自动往下读。
		int ch = 0;
		while((ch=fr.read())!=-1)
		{
			System.out.println(
		}
		fr.close();
	}
}
第二种方式:利用方法 int read(char[] cbuf):将字符读入数组
			返回的值是读取的字符数。
import java.io.*;
class FileReaderDemo2 
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("demo.txt");
		//定义一个字符数组。用于存储读到字符。
		//该read(char[])返回的是读到字符个数。
		char[] buf = new char[1024];
		int num = 0;
		while((num=fr.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,num));
		}
		fr.close();
	}
}<span style="font-family:SimSun;">
</span>

4、字符流的综合练习

需求:将c盘中的一个文本文件复制到D盘

示例:

复制的原理:
其实就是将C盘下的文件数据存储到D盘的一个文件中。

步骤:
1,在D盘创建一个文件。用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
*/
import java.io.*;
class CopyText 
{
	public static void main(String[] args) throws IOException
	{
		copy_2();
	}
	//第二种读取文件的方式:即将数据先读入到数组中的方式。
	public static void copy_2()
	{
		FileWriter fw = null;
		FileReader fr = null;
		try//对异常进行处理
		{
			fw = new FileWriter("SystemDemo_copy.txt");
			fr = new FileReader("SystemDemo.java");
			//定义一个数组来存放读取到的数据
			char[] buf = new char[1024];
			
			int len = 0;
			while((len=fr.read(buf))!=-1)
			{
				//将数组中的有效数据写入流中
				fw.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("读写失败");
		}
		finally//此代码块中,存放是关闭资源的操作,由于是必须关闭资源,所以放在finally代码块中
		{
			if(fr!=null)
				try
				{
					fr.close();
				}
				catch (IOException e)
				{
				}
			if(fw!=null)
				try
				{
					fw.close();
				}
				catch (IOException e)
				{
				}
		}
	}
	//从C盘读一个字符,就往D盘写一个字符。
	public static void copy_1()throws IOException
	{
		//创建目的地。
		FileWriter fw = new FileWriter("RuntimeDemo_copy.txt");
		//与已有文件关联。
		FileReader fr = new FileReader("RuntimeDemo.java");
		int ch = 0;
		while((ch=fr.read())!=-1)
		{
			fw.write(ch);
		}
		fw.close();
		fr.close();
	}
}

三、字节流

1.字节流是用于操作图片的,即用操作媒体信息的。

2.字节流的读写流是:FileInputStream和FileOutputStrean

FileInputStream是对文件进行读取操作;
FileOutStream是对将信息向文件中写入。

3.FileInputStream

读取文件的方式有三种:第一,利用字节流的特有方法:int available()返回文件中的字节数

第二,用int read()即一次读取一个字节的方式

第三,用int read(数组)即将读取到的字节存入到数组中。

例子:需求,读取一个文件数据,并打印在控制台上

代码:

<span style="font-family:SimSun;font-size:18px;">import java.io.*;
class  FileStream
{
	public static void main(String[] args) throws IOException
	{
		readFile_3();
	}
	//利用字节流的特有方法进行读取。只是用此方法时文件不能太大,否则内存会溢出。
	public static void readFile_3()throws IOException
	{
		FileInputStream fis = new FileInputStream("fos.txt");
		//int num = fis.available();
		byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。
		//将信息读入数组中
		fis.read(buf);
		System.out.println(new String(buf));
		fis.close();
	}
	//利用方法int read(数组)来读取信息
	public static void readFile_2()throws IOException
	{
		FileInputStream fis = new FileInputStream("fos.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();	
	}
	//利用一次读取一个字符的方法来读取,即int read()
	public static void readFile_1()throws IOException
	{
		FileInputStream fis = new FileInputStream("fos.txt");

		int ch = 0;

		while((ch=fis.read())!=-1)
		{
			System.out.println((char)ch);
		}
		fis.close();
	}
}</span>

4.字节流的综合运用

/*
复制一个图片
思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。
4,关闭资源。
*/
import java.io.*;
class  CopyPic
{
	public static void main(String[] args) 
	{
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try
		{
			//定义输出流与文件相关联
			fos = new FileOutputStream("c:\\2.bmp");
			//定义输入流与要读取的文件相关联
			fis = new FileInputStream("c:\\1.bmp");
			//定义一个数组,将信息读入数组中
			byte[] buf = new byte[1024];
			int len = 0;
			//通过for循环来将文件中的信息读取完
			while((len=fis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("复制文件失败");
		}
		finally//关闭资源
		{
			try
			{
				if(fis!=null)
					fis.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("读取关闭失败");
			}
			try
			{
				if(fos!=null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}

四、字符流缓冲区

1.字符流的缓冲区,,内部封装的是数组

读取缓冲区BufferedReader,提供了方法:String readLine(),即一次读取一行

返回的是读取到的改行的字符串,不包含任何行终止符。如果已经达到末尾,则返回null

写入缓冲区BufferedWriter,提供了方法,newLine()即换行
2.缓冲区的综合运用

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

import java.io.*;
class  CopyTextByBuf
{
	public static void main(String[] args) 
	{
		//定义两个流缓冲区:读取流缓冲区和写入流缓冲区
		BufferedReader bufr = null;
		BufferedWriter bufw = null;
		try
		{
			bufr = new BufferedReader(new FileReader("BufferedWriterDemo.java"));
			bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt"));
			//通过循环利用方法readLine,一次读取一行的操作来进行读取信息
			String line = null;
			//readLine方法,底层调用的仍是read()方法
			while((line=bufr.readLine())!=null)
			{
				bufw.write(line);//将读取到的信息写入缓冲区流中
				bufw.newLine();//利用写入流缓冲区的换行功能来换行,因为line中并不包括换行符
				bufw.flush();//刷新缓冲区,记住,只要用到缓冲区就要记得刷新。
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("读写失败");
		}
		finally//关闭系统资源
		{
			try
			{
				if(bufr!=null)
					bufr.close();//由于关闭缓冲区,就是关闭缓冲区中的流对象,
						    //最终关闭的是系统资源,所以此处就不用再写关闭流对象了。
			}
			catch (IOException e)
			{
				throw new RuntimeException("读取关闭失败");
			}
			try
			{
				if(bufw!=null)
					bufw.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}

五、字节流缓冲区

包括BufferedInputStream和BufferedOutputStream,底层封装的是数组,所以读取时,不用再用read(数组)来读取了
注意:
1.BufferedInputStream并没有功能readLine(),readLine()功能是字符流缓冲区特有的。

2.BufferedOutputStream并没有功能newLine(),newLine()功能是字符流读出流缓冲区特有的。

对字节流缓冲区的综合运用:

/*
演示mp3的复制。通过缓冲区。
BufferedOutputStream
BufferedInputStream
*/
import java.io.*;
class  CopyMp3
{
	public static void main(String[] args) throws IOException
	{
		long start = System.currentTimeMillis();
		copy();
		long end = System.currentTimeMillis();

		System.out.println((end-start)+"毫秒");
	}

	//通过字节流的缓冲区完成复制。
	public static void copy()throws IOException
	{
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
		int by = 0;
		while((by=bufis.read())!=-1)
		{
			bufos.write(by);
		}
		bufos.close();
		bufis.close();	
	}
}

六、转换流

字节流和字符流之间的转换流

1.读取流转换流:InputStreamReader,是字节流通向字符流的桥梁

2.写入流转换流:OutputStreamReader:是字符流通向字节流的桥梁

3.InputStream System.in:对应的标准输入设备:键盘,返回值为InputStream

PrintStream System.out:对应的标准输出设备:控制台,返回值为PrintStream,即是OutputStream的子类。

4.键盘录入的最常见写法为:BufferedReader bufr = 

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

输出设备的最常见的写法

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

综合运用:

需求:
通过键盘录入数据。
当录入一行数据后,就将该行数据进行打印。
如果录入的数据是over,那么停止录入。

import java.io.*;
class  TransStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		/*获取键盘录入对象。
		InputStream in = System.in;

		//将字节流对象转成字符流对象,使用转换流。InputStreamReader
		InputStreamReader isr = new InputStreamReader(in);

		//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader

		BufferedReader bufr = new BufferedReader(isr);
		*/
			
		//将上面简化为如下,也是键盘的最常见写法。
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
		/*输处设备流的转换
		OutputStream out = System.out;
	        OutputStreamWriter osw = new OutputStreamWriter(out);
		BufferedWriter bufw = new BufferedWriter(osw);*/
			
		//输出设备的最常见的写法
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}
		bufr.close();
	}
}
5. 转换流一般伴有字符编码
常用到的编码表示UTF-8和GBK,一般咱们所使用的文件的编码表是GBK
UTF-8是三个字节代表一个字符,而GBK是两个字节代表一个字符
例子:

import java.io.*;
class EncodeStream 
{
	public static void main(String[] args) throws IOException 
	{
			//writeText();
			readText();
	}
	//对文件以指定的编码表进行读取
	public static void readText()throws IOException 
	{
		//在流中执行了以彪编码表GBK来读取文件中的信息
		InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");
		//将文件读入数组中
		char[] buf = new char[10];
		int len = isr.read(buf);
		//将数组转换为字符串
		String str = new String(buf,0,len);
		System.out.println(str);
		isr.close();//关闭资源
	}
	//以指定的编码表形式向文件中写入信息。
	public static void writeText()throws IOException 
	{
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
		osw.write("你好");
		osw.close();
	}
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值