第九部分:带缓冲的的字节流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);
目的: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()