黑马程序员--Java基础--IO流(二)

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

第九部分:带缓冲的的字节流BufferedOutputStream、BufferedInputStream

1、带缓冲区的字节流有两个:

输出流:BufferedOutputStream。写入文件的方法是write,write每次写入一个字节

输入流:BufferedInputStream。调用的方法是read,和BufferedReader使用的readLine方法不同的是,read每次读取一个字节。

2、write和read方法的特点:

write:进行强转动作,只写入int类型的最低八位。

read:进行向上提升动作,在前面补0,保证不是-1的情况出现。

3、使用带缓冲区的字节流进行MP3文件复制

class  
{
	public static void main(String[] args) 
	{
		long start = System.currentTimeMillis();
		copy_1();
		long end = System.currentTimeMillis();
	}
	//通过字节流的缓冲区完成复制
	public static void copy_1() throws IOException
	{
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("d:\\old.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("d:\\new.mp3"));
		int by = 0;
		while((by=bufis.read())!=-1)
		{
			buffos.write(by);
		}
		bufos.close();
		bufis.close();
	}
}

第十部分:读取键盘录入

读取键盘录入有两种方式:

1、直接使用InputStream的read方法进行读取,每次读取的是一个字节,返回的是int类型,即输入字符的字节码,需要强制类型转换

public class HelloDemo {
	public static void main(String[] args) throws Exception{
		InputStream in = System.in;
		int ch = 0;
		while((ch=in.read())!=-1)//调用
		{
			System.out.print((char)ch);//每次打印一个字符,需要进行char类型转换
		}
	}
}

2、使用读取转换流InputStreamReader。

在第一种方法中通过刚才的键盘的录入一行数据,发现其实就是读一行数据的原理,也就是readLine方法。
能不能直接使用readLine方法完成键盘录入一行数据的读取呢?
readLine方法是字符流BufferedReader类中的方法
而键盘录入的read方法是字节流InputStream的方法。


那么能不能将字节流转换成字符流,再使用字符流缓冲区的readLine方法呢?
答案就是使用InputStreamReader 读取转换流。InputStreamReader 属于字符流,因此可以作为参数传入BufferedReader。它可以将字节流转成字符流,是字节流通向字符流的桥梁。

代码示例:

class  
{
	public static void main(String[] args) throws IOException
	{
		//获取键盘录入对象
		InputStream in = System.in;
		//将字节流对象转成字符流对象,使用转换流,InputStreamReader
		InputStreamReader isr = new InputStreamReader(in);
		//为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
		BufferedReader bufr = new BufferedReader(isr);

		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			System.out.println(line.toUpperCase());
		}
		bufr.close();
	}
}
从以上代码中可以抽取出键盘录入方式的简写:

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));</span>
这句语句需要牢记。

3、写入转换流OutputStreamWriter

刚才InputStreamReader是字节流通向字符流的桥梁,那OutputStreamWriter是由字符流通向字节流的桥梁!

OutputStreamReader只接受参数字节流对象OutputStream

需求:从键盘录入,在控制台输出,使用OutputStreamWriter

代码示例:

public class HelloDemo {
	public static void main(String[] args) throws Exception {
		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();//使用的BufferedWriter的功能,因此需要换行和刷新。
			bufw.flush();
		}
		bufr.close();
	}
}

第十部分:流操作规律

1、要进行流操作,必须有三个明确:

a、明确源和目的

源:输入流。分为字节流InputStream,字符流Reader

目的:输出流。分为字节流OutputStream,字符流Writer

b、操作的数据是否为纯文本。

是:使用字符流

不是:使用字节流。

c、当体系明确后,再明确要使用哪个具体的对象。可以通过设备来进行区分。

源设备:内存(可以使用InputStream、Reader)、硬盘(FileReader、FileInputStream)、键盘(需要InputStreamReader的BufferedReader)

目的设备:内存(可以使用OutputStream、Writer)、硬盘(FileWriter、FileOutputputStream)、键盘(需要OutputStreamWriter的BufferedWriter)

d、可以考虑是否用缓冲区技术


2、例子举例:

需求:将键盘录入的数据保存到一个文件中。

分析过程:

a、

源:可以选择InputStream和Reader

是不是纯文本:

是,使用Reader。

设备:键盘,对应的对象是System.in。

因为应该使用Reader,而System.In对应的是字节流,因此为了操作键盘的文本数据方便,使用InputStreamReader转成字符流按照字符串操作是最方便的。

因此用了Reader体系中的转换流InputStreamReader。

需要缓冲区吗?

需要,使用BufferedReader。

因此得出:

InputStreamReader isr = new InputStreamReader(System.in)
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream和Writer

是否是纯文本?是!Writer。

设备:硬盘的一个文件,使用FileWriter。

需要缓冲区吗?

需要!使用BufferedWriter

FileWriter fw = new FileWriter("c.txt");
BufferedWriter bufw = new BufferedWriter(fw);


扩展:想要把录入的数据按照指定的编码表(UTF-8),将数据存入文本。

目的:OutputStream和Writer
是否是纯文本?是!Writer。
设备:硬盘。一个文件。使用FileWriter.
但是FileWriter是使用默认编码表GBK。
但是存储时,需要加入指定的编码表utf-8,而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流,而且还可以操作文件的字节输出流,使用FileOutputStream

需要缓冲区!

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
BufferedWriter bufw = new BufferedWriter(osw);

代码示例

class  
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));

		BufferedWriter bufr = 
				new BufferedWriter(new OutputStreamWriter(new FileOutputStream("deemo.txt"),"UTF-8");
		

		String line = null;
		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}
		bufr.close();
	}
}

总结:所以记住转换流什么时候使用?

字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要转换流。
InputStreamReader的直接子类是FileReader,FileReader的默认码表是GBK。


第十一部分:File类

1、概述:

用于将文件或者文件夹封装成对象,方便对文件和文件夹的属性信息进行操作。File对象可以作为参数传递给流的构造函数

2、方法

a、 创建
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false和输出流不一样,输出流对象一建立就创建文件。而且文件存在的情况下会覆盖

代码示例:

File f = new File("D:\\file.txt");
f.createNewFile();

boolean mkdir():创建文件夹

代码示例:

//创建单极目录
File dir = new File("D:\\abc");
dir.mkdir();

boolean mkdirs():创建多级文件夹

代码示例:

//创建多级目录
File dir = new File("D:\\abc\\a\\s\\d");
dir.mkdirs()

b、 删除

boolean delete():删除失败返回false

代码示例:

f.delete();

void deleteOnExit():在程序退出时删除指定文件

代码示例:

//如果为了保证在发生异常的情况下也能删除掉文件
f.deleteOnExit();

c、 判断

boolean exists():文件是否存在

代码示例:

File f = new File("file.txt");
//记住在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在
//通过exists判断
f.exists();

boolean isDirectory();判断是否是目录

代码示例:

f.isDirectory();

boolean ifFile();判断是否是文件

代码示例:

f.isFile();
boolean isHidden();

boolean isAbsolute();是否是绝对路径
d、 获取信息
String getName()

String getPath()

代码示例:

File f = new File("file.txt");
f.getPath();//返回的是file.txt

String getParent():该方法返回的是绝对路径中的父目录,如果没有指定绝对路径,返回的是null。如果相对路径中有上一层目录,那么该目录就是返回结果

long lastModified()

String getAbsolutePath()

代码示例:

f.getAbsolutePath();//返回的是全路径

long length()




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值