黑马程序员----JAVA基础----IO流_1

来源:互联网 发布:华为liteos 源码下载 编辑:程序博客网 时间:2024/05/20 10:13

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、IO流

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

流按数据操作可分为字节流和字符流(处理文本数据);

a,字节流:读取文字字节的数据

b,字符流:在字节流的基础上,不直接操作而是先查找指定编码表,获取对应的文字。简单说:字符流就是字节流+编码表。

流按流向可分为输入流和输出流。

a,输入流:从外部设备读数据到内存中。

b,输出流:将内存中的数据写到外部设备上。

二、IO流体系

IO流有四个顶层基类:

字节流抽象基类:InputStream、OutputStream

字符流抽象基类:Reader、Writer

对于IO流体系内的类的名称来说:子类都以父类名作为后缀,子类名的前缀表示该类的功能

三、IO流使用

1,创建一个可以向文件中写入数据的字符输出流对象及一些细节问题

import java.io.FileWriter;import java.io.IOException;public class IODemo {private static final String LINE_SEPARATOR = System.getProperty("line.separator");public static void main(String[] args) throws IOException{/* * 在创建字符流对象时,必须明确与其关联的文件 * 会抛出一个IO异常,原因:可能无法关联 */// 用字符输出流关联一个文本文件,文件存在,会覆盖其中的内容,如果该文件不存在,则创建一个文本文件// 如果需要续写文件,则在构造函数中加入trueFileWriter fw = new FileWriter("demo.txt");//FileWriter fw = new FileWriter("demo.txt",true); //使用该流,就可以续写,而不会发生覆盖// 调用FileWriter中的write()方法,写入数据,数据被写入临时数据缓冲区中fw.write("abcdefg");/* * 换行:在windos系统中换行符:\r\n,在Linux系统中:\n * 有两种方法,一是+\r\n;一种是用系统提供的方法System.getProperty("line.separator") * 第二种方法不用考虑系统问题 */fw.write("hehe"+"\r\n"+"heihei");fw.write("hehe"+LINE_SEPARATOR+"heihei");// 运行flus()方法,将缓冲区的数据刷新到文本文件中fw.flush();// 关闭流,关闭资源,关闭前会调用flush刷新缓冲区的数据到文本文件中,因此flush可以省略fw.close();// 关闭流后再写入数据,就会引起IOException//fw.write("cde");}}
2,IO异常处理

import java.io.FileWriter;import java.io.IOException;public class IODemo2 {private static final String LINE_SEPARATOR = System.getProperty("line.separator");public static void main(String[] args) throws IOException {// 先创建字符输出流对象FileWriter fw = null;try{// 关联文件操作失败会引发IOException,因此将其放到try block中fw = new FileWriter("demo.txt");fw.write("abc"+LINE_SEPARATOR+"def");}catch(IOException e){// 处理异常}finally{// 表示一定要关闭资源// 加上判断条件,当fw不为null时才可以关闭,否则会引发NullPointerExceptionif(fw!=null)try{fw.close();}catch(IOException e){System.out.println(e.toString());}}}}

3,读取一个文件,将文件的内容打印到控制台上。

<pre name="code" class="html">import java.io.FileReader;import java.io.IOException;public class IODemo3 {public static void main(String[] args) throws IOException {// 用读取流关联文件,文件不存在则会引发FileNotFoundExceptionFileReader fr = new FileReader("demo.txt");// 读一次//show1(fr);// 循环读取方式//show2(fr);// 使用字符数组,将数据读取到数组中show3(fr);fr.close();}private static void show3(FileReader fr) throws IOException {char[] buf = new char[1024];//一般将数组的大小设为1024,如果数字是固定的,可以将其设置为常量int len=0;while((len=fr.read(buf))!=-1){// 使用String构造函数,将字符数组转换成字符串System.out.println(new String(buf,0,len));}}private static void show2(FileReader fr) throws IOException {int ch = 0;while((ch=fr.read())!=-1){System.out.print((char)ch);//使用强制转换,将int转为char类型}}private static void show1(FileReader fr) throws IOException {int ch = fr.read();// 用读取流的read()方法读取数据,返回读取到的字符数,读到结尾返回-1System.out.print((char)ch);//使用强制转换,将int转为char类型}}
4,字符流的缓冲区。缓冲区提高了数据的读写效率,对应类:BufferedReader、BufferedWriter。

缓冲区要结合流才可以使用,在流的基础上对流的功能进行增强。

缓冲区常用方法:readlLine()、newLine()

注意:使用缓冲区一定要使用flusn()方法!!!

使用缓冲区与流结合高效读写数据,并加上异常处理:

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class BufferedDemo {public static void main(String[] args) {// TODO Auto-generated method stub// 创建缓冲区对象BufferedReader bufr = null;BufferedWriter bufw = null;try{// 与流相关联bufr = new BufferedReader(new FileReader("demo.txt"));bufw = new BufferedWriter(new FileWriter("copydemo.txt"));String line = null;// readLine()是读取一行while((line=bufr.readLine())!=null){bufw.write(line);bufw.newLine();// 换行bufw.flush();// 使用缓冲区一定要刷新}}catch(IOException e){System.out.println(e.toString());}finally{// 当bufr和bufw不为空时,才可以关闭流if(bufr!=null)try{bufr.close();}catch(IOException e){}if(bufw!=null)try{bufw.close();}catch(IOException e){}}}}

5,装潢设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决

装潢和继承都能进行功能的扩展增强,那么二者的区别是什么呢?用继承来进行功能的扩展,

会导致继承体系越来越臃肿,不够灵活。装饰比继承更为灵活

注意:装饰类和被装饰类必须所属同一个接口或者父类!!!

装饰类:BufferedReader、BufferedWriter、LineNumberReader等。

其中LineNumberReader的特有方法:setLineNumber(int index)、getLineNumber()(返回行号)

6,字节流两个常用子类FileInputStream、FileOutputStream,该类的read()方法一次读取一个字节,available()方法可以

返回与其关联文件的字节数

字符流只可以处理文本文件,而字节流既可以处理文本文件,又可以处理非文本文件。

注意在使用BufferedOutputStream时不用使用flush()方法,原因:

字符流底层使用的还是字节流,因为字符流融合了编码表,所以可以读写字符。

字符流写入文本数据时,需要先将文本数据写入字符流中,对照编码表转换成字节数据,然后flush进目的地。

字节流中是字节数据不需要转换,所以可以直接写入目的地。

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class CopyMediaDemo {public static void main(String[] args) throws IOException {// 方法1//show1();// 方法2show2();}private static void show2() throws FileNotFoundException, IOException {FileInputStream fis = new FileInputStream("Desert.jpg");FileOutputStream fos = new FileOutputStream("Desert_copy.jpg");byte[] buf = new byte[1024];int len = 0;len=fis.read(buf);System.out.println(len);// 如果read()方法里不加数组buf,那么len就是读到的字节的值// 加上buf后,len表示读进buf的字节数量//while((len=fis.read())!=-1){//fos.write(buf,0,len);//}while((len=fis.read(buf))!=-1){fos.write(buf,0,len);}fos.close();}/** *  */private static void show1() {BufferedInputStream bis = null;BufferedOutputStream bos = null;try {// 将缓冲区与流相关联bis = new BufferedInputStream(new FileInputStream("Desert.jpg"));bos = new BufferedOutputStream(new FileOutputStream("Desert_copy.jpg"));int ch=0;while((ch=bis.read())!=-1){/* * 字符流底层使用的还是字节流,因为字符流融合了编码表,所以可以读写字符。 * 字符流写入文本数据时,需要先将文本数据写入字符流中,对照编码表转换成字节数据, * 然后flush进目的地。字节流中是字节数据不需要转换,所以可以直接写入目的地 */bos.write(ch);}} catch (Exception e) {e.printStackTrace();}finally{// 关闭流,释放资源,记着判断流是否为空if(bos!=null)try {bos.close();} catch (Exception e) {e.printStackTrace();}if(bis!=null)try {bis.close();} catch (Exception e) {e.printStackTrace();}}}}

7,读取键盘录入的数据并打印在控制台上

InputStreamReader 和 OutputStreamWriter是字节流与字符流之间的桥梁

InputStreamReader:字节到字符的桥梁,解码。

OutputStreamWriter:字符到字节的桥梁,编码。

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class KeyDemo {public static void main(String[] args) throws IOException {// TODO Auto-generated method stub// 创建字节流接InputStream in = System.in;// 读取一次//show1(in);// 无限读取,直到遇到特定标记停止//show2(in);// 通过字节字符桥梁来完成键盘录入及打印操作show3(in);// 流关闭后再创建新流会产生异常IOException//InputStream in1 = System.in;//int ch1 = in.read();//System.out.println(ch1);}private static void show3(InputStream in) throws IOException {// InputStreamReader和OutPutStreamWriter是字节流与字符流的桥梁BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));String str = null;while((str=bufr.readLine())!=null){if("over".equals(str))break;bufw.write(str);bufw.newLine();bufw.flush();}}private static void show2(InputStream in) throws IOException {// 创建一个StringBuilder用于接收数据StringBuilder sb = new StringBuilder();int ch=0;while((ch=in.read())!=-1){// 当回车时,输出键盘录入的内容if(ch=='\r')continue;if(ch=='\n'){String temp = sb.toString();// 当输入内容为over时就结束if("over".equals(temp))break;// 将键盘录入数据转成大写输出System.out.println(temp.toUpperCase());// 输出数据后清空sbsb.delete(0, sb.length());}elsesb.append((char)ch);// 将ch转换成字符存入sb中}}private static void show1(InputStream in) throws IOException {int ch = in.read();// 阻塞式System.out.println(ch);in.close();}}


8,流的操作规律

a,明确源和目的源:InputStreamReader目的: OutputStreamWriter

b,明确数据是否是纯文本数据源:是纯文本用Reader,否InputStream目的:是纯文本用Writer,否OutputStream

c,明确具体的设备源:硬盘(File)、键盘(System.in)、内存(数组)、网络(Socket流)目的设备与源相同。

d,是否需要额外功能是否需要高效?是,加Buffer

四、File类

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

import java.io.File;import java.io.FileFilter;import java.io.FilenameFilter;import java.io.IOException;public class FileDemo {public static void main(String[] args) throws IOException {// 可以建一个存在的和不存在的文件或者目录封装成对象// 构造函数的集中不同形式File f1 = new File("demo.txt");File f2 = new File("D:\\JAVA\\Blog\\","demo.txt");File f3 = new File("D:\\JAVA\\Blog\\");File f4 = new File(f3,"demo.txt");// 字段File.separator 对于不同的操作系统都可以应用File f5 = new File("D:"+File.separator+"JAVA"+File.separator+"Blog"+File.separator+"demo.txt");/* * File类常见方法 * 1,获取:文件名称、大小、路径、修改时间等 * 2,创建与删除 * 3,判断: */// 获取System.out.println("getName():"+f1.getName());System.out.println("length():"+f1.length());System.out.println("path:"+f1.getPath());System.out.println("absolutePath:"+f1.getAbsolutePath());//获取绝对路径System.out.println("lastModified:"+f1.lastModified());// 创建与删除File file = new File("aaa.txt");// 和输出流不一样,如果文件不存在则创建,如果存在就不创建。输出流是在与不在都会创建,在就覆盖boolean b = file.createNewFile();boolean b1 = file.delete();// 删除文件// 创建目录File file1 = new File("abc");boolean b2 = file1.mkdir();boolean b3 = file1.delete();// 注意:如果要删除的文件内部有其他文件,则无法删除// 创建多级目录File file2 = new File("abc\\def\\mnk\\ss");boolean b4 = file2.mkdirs();boolean b5 = file2.delete();// 删除的ss文件夹,不会都删除// 判断File file3 = new File("demo.txt");System.out.println(file3.exists());//是否存在,当文件是未知时,应该先判断是否存在System.out.println(file3.isDirectory());//是不是目录System.out.println(file3.isFile());// 是不是文件// renameTo()File file4 = new File("demo.txt");File file5 = new File("DEMO.txt");File file6 = new File("d:\\demo_copy.txt");//file4.renameTo(file5);//同目录下重命名,//file4.renameTo(file6);//非同文件下,移动并重命名// listRoots获取根目录列表File[] file7 = File.listRoots();for(File files:file7){System.out.println(files);}//File file8 = new File("d:\\");System.out.println(file8.getFreeSpace());// 盘符的可用空间System.out.println(file8.getUsableSpace());// 盘符的可用空间System.out.println(file8.getTotalSpace());// 盘符的大小// list获取当前目录下的文件及文件夹名称,包含隐藏文件// 注意:调用list方法的File类对象中封装的必须是目录,否则会发生NullPointerException// 如果访问系统级目录也会发生NullPointerException// 如果目录存在但没有内容,会返回一个长度为0的数组String[] names = file8.list();for(String name:names){System.out.println(name);}// FilenameFilter 获取指定类型的文件File file9 = new File("E:\\数据\\BLS900");String[] strs = file9.list(new FilterByMnd());for(String str:strs){System.out.println(str);}File[] files = file9.listFiles(new FilterByHidden());for(File f:files){System.out.println(f);}}}class FilterByMnd implements FilenameFilter{//创建构造函数,可以方便过滤某后缀的文件//private String suffix;////public FilterByMnd(String suffix) {//super();//this.suffix = suffix;//}//@Override//public boolean accept(File dir, String name) {//// TODO Auto-generated method stub//return name.endsWith(suffix);//}@Overridepublic boolean accept(File dir, String name) {// TODO Auto-generated method stubreturn name.endsWith(".mnd");}}class FilterByHidden implements FileFilter{@Overridepublic boolean accept(File pathname) {// TODO Auto-generated method stubreturn !pathname.isHidden();}}





0 0
原创粉丝点击