知识列表
- IO概述
- 字符流
- IO异常
- FileReader
- 复制文本文件
- BufferedWriter
- BufferedReader
- InputStream和OutputStream
- 复制图片文件
- 转换流,读取键盘录入
- 流对象操作规律
- 改变标准输入输出设备
- File类
- Properties
- 打印流
- 合并流
1)IO概述
字符流和字节流。
字节流两个基类:
InputStream?? OutputStream字符流两个基类:
Reader Writer
2)字符流
IO流是用于操作数据的,数据最常见形式是文件。
例如:在硬盘上创建一个文件并写入一些文字数据。
FileWriter:
是一个专门用于操作文件的Writer子类对象
1: class FileWriterDemo2: {3: public static void main(String[] args) throws IOException4: {5: //创建一个FileWriter对象,该对象初始化时就要明确被操作的文件。6: //在制定目录上创建一个demo.txt的文件,如果该目录下存在同名文件,旧文件将被覆盖。8: FileWriter fw = new FileWriter("demo.txt");9: //调用write方法,将字符串写入到流中。10: fw.write("abcde");11: //刷新流对象中的缓冲中的数据,将数据写入文件中。13: //fw.flush();14: //关闭流资源17: fw.close();18: }19: }?
fw.close()用于关闭流资源,关闭之前会自动刷新缓冲区中的数据,与flush()的区别:flush只刷新不关闭资源,close既刷新又关闭资源。
如果要续写文件内容,而不是覆盖同名文件,就给FileWriter传递一个true参数,表示续写不覆盖。
1: class FileWriterDemo32: {3: public static void main(String[] args) throws IOException4: {5: //传递true参数,表示续写demo.txt文件,不覆盖旧文件。6: FileWriter fw = new FileWriter("demo.txt",true);8: fw.write("hello world!");10: fw.close();11: }12: }13:
3)IO异常
IO异常的处理方式
finally中定义关闭资源的动作,关闭之前要先判断。
1:2: class FileWriterDemo23: {4: public static void main(String[] args)5: {6: FileWriter fw = null;7: try8: {9: fw = new FileWriter("demo.txt");10: fw.write("abcdefg");11: }12: catch (IOException e)13: {14: System.out.println("catch:"+e.toString());15: }16: finally17: {18: try19: {20: if(fw!=null)21: fw.close();22: }23: catch (IOException e)24: {25: System.out.println(e.toString());26: }27:28: }29:30: }31: }
4)FileReader :
读取文件有两种方式:
第一种是每次读取一个字符:
1: class FileReaderDemo2: {3: public static void main(String[] args) throws IOException4: {5: //创建一个文件读取流对象,和指定名称的文件相关联。6: //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException7: FileReader fr = new FileReader("demo.txt");8: //调用读取流对象的read方法。9: //read():一次读一个字符。而且会自动往下读。10: int ch = 0;11: while((ch=fr.read())!=-1)12: {13: System.out.println((char)ch);14: }15: fr.close();16: }17: }
第二种是每次读取到字符数组中:
1: class FileReaderDemo22: {3: public static void main(String[] args) throws IOException4: {5: FileReader fr = new FileReader("demo.txt");6: //定义一个字符数组。用于存储读到字符。7: //read(char[])返回的是读到字符个数。8: char[] buf = new char[1024];9: int num = 0;10: while((num=fr.read(buf))!=-1)11: {12: System.out.println(new String(buf,0,num));13: }15: fr.close();16: }17: }
5)复制文本文件
原理:就是将一个文件中的数据存储到另一个文件中。
步骤:
1,在d盘创建一个文件,用于存储c盘文件中的数据。
2,定义读取流和源文件相关联。
3,通过不断的读写完成数据存储。
4,关闭资源。1: class CopyDemo2: {3: public static void main(String[] args) throws IOException4: {5: copy();6: }7: public static void copy()throws IOException//为了简化书写,没有处理异常8: {9: //创建目标文件。10: FileWriter fw = new FileWriter("demoCopy.txt");11:12: //与源文件相关联。13: FileReader fr = new FileReader("demo.txt");14: int ch = 0;15: while((ch=fr.read())!=-1)16: {17: fw.write(ch);18: }19: fw.close();20: fr.close();21: }22: }
6)BufferdWriter:
BufferdWriter是字符写入流,可以提高写入效率
BufferdWriter中的方法newLine()是以个跨平台的换行符。
2: FileWriter fw = new FileWriter("buf.txt");5: //将需要被提高效率的流对象作为参数传递给缓冲区的构造函数6: BufferedWriter bufw = new BufferedWriter(fw);7: for(int x=1; x<5; x++)8: {9: bufw.write("abcd"+x);10: bufw.newLine();11: bufw.flush();12: }13: //只要用到缓冲区,就要刷新。14: //bufw.flush();15: //关闭缓冲区,就是在关闭缓冲区中的流对象。16: bufw.close();
7)BufferedReader:
BufferedReader是字符读取流缓冲区:
BufferedReader中方法 readLine(),每次读取一整行,是读取文件更加方便。当返回null时,表示读到文件末尾。readLine方法只返回回车符之前的内容,不返回回车符。
1: //创建一个读取流对象和文件相关联。2: FileReader fr = new FileReader("buf.txt");3: //BufferedReader可以提高读取效率,将fr作为参数传递给BufferedReader的对象即可。4: BufferedReader bufr = new BufferedReader(fr);5: String line = null;6: while((line=bufr.readLine())!=null)7: {8: System.out.print(line);9: }10: bufr.close();
8)InputStream和OutputStream:
InputStream和OutputStream和字符流的使用方法差不多。
OutputStream,字节写入流
1: FileOutputStream fos = new FileOutputStream("fos.txt");2: fos.write("abcde".getBytes());3: fos.close();
初始化时就需要和存储文件相关联。
同样需要关闭资源
InputStream,字节读取流:
读取时可以定义好一个刚刚好的缓冲区,或者定义一个数组[1024*x],x表示长度是1024的整数倍的数组,一般使用后者,防止文件过大时造成内存溢出。
1: FileInputStream fis = new FileInputStream("fos.txt");3: byte[] buf = new byte[1024];4: int len = 0;5: while((len=fis.read(buf))!=-1)6: {7: System.out.println(new String(buf,0,len));8: }10: fis.close();
初始化时需要和源文件相关联
读取完成以后同样也需要关闭资源
9)复制图片文件
大致步骤:
1,字节读取流对象和图片关联。
2,字节写入流对象创建一个图片文件存储读取到的数据。
3,循环读写。
4,关闭资源。
1: FileOutputStream fos = null;2: FileInputStream fis = null;3: try4: {5: fos = new FileOutputStream("c:\\1copy.jpg");6: fis = new FileInputStream("c:\\1.jpg");10: int len = 0;12: while((len=fis.read(buf))!=-1)13: {14: fos.write(buf,0,len);15: }16: }17: catch (IOException e)18: {19: throw new RuntimeException("复制文件失败");20: }21: finally22: {23: try24: {25: if(fis!=null)26: fis.close();27: }28: catch (IOException e)29: {30: throw new RuntimeException("读取关闭失败");31: }32: try33: {34: if(fos!=null)35: fos.close();36: }37: catch (IOException e)38: {39: throw new RuntimeException("写入关闭失败");40: }41: }
分别关闭读取流和写入流。
10)转换流,读取键盘录入
读取键盘录入时,需要每次读取一行,readLine方法是字符流BufferedReader类中的方法方法,而键盘录入的read方法是字节流InputStream的方法,此时就需要转换流:
InputStreamReader
12: //获取键盘录入13: BufferedReader bufr =14: new BufferedReader(new InputStreamReader(System.in));
如果不定义结束标记,键盘录入就结束不了。
将键盘录入的数据打印在控制台并转换为大写,将over作为结束标记:
1: //获取键盘录入对象。2: //InputStream in = System.in;3:4: //将字节流对象转成字符流对象,使用转换流。InputStreamReader5: //InputStreamReader isr = new InputStreamReader(in);6:7: //为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader8: //BufferedReader bufr = new BufferedReader(isr);9: //键盘的最常见写法。10: BufferedReader bufr =11: new BufferedReader(new InputStreamReader(System.in));12: BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));13: String line = null;14:15: while((line=bufr.readLine())!=null)16: {17: if("over".equals(line))18: break;19: bufw.write(line.toUpperCase());20: bufw.newLine();21: bufw.flush();22: }23:24: bufr.close();
11)流对象操作规律
通过键盘录入的例子分析出流操作的大致规律:
1,需求:将键盘录入打印在控制台上
源:键盘录入。
目的:控制台。2,需求:想把键盘录入的数据存储到一个文件中。
源:键盘。
目的:文件。3,需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台。因为流对象很多,为了便于选取合适的流对象进行操作,分析出流操作的基本规律:
通过三个明确来完成。
1,明确源和目的。
源:输入流。InputStream? Reader
目的:输出流。OutputStream? Writer。
2,操作的数据是否是纯文本。
是:字符流。
不是:字节流。3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。举例说明:
1,复制文本文件。
源:是读取流,选择InputStream或Reader?
是否纯文本:是,选择Reader设备:硬盘。
Reader体系中可以操作文件的对象是 FileReader
需要提高效率,加入Reader体系中缓冲区 BufferedReader.?
BufferedReader bufr = new BufferedReader(new FileReader("1.txt"));目的:写入流,选择OutputStream或者Writer
是纯文本,选择Writer设备:硬盘
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率:是!。加入Writer体系中缓冲区 BufferedWriter
BufferedWriter bufw = new BufferedWriter(new FileWriter("1copy.txt"));2,需求:将键盘录入的数据保存到一个文件中。
源:InputStream Reader
是不是纯文本?是!Reader
设备:键盘。对应的对象是System.in.
System.in对应的是字节流吗,为了操作键盘的文本数据方便,转成字符流用了Reader体系中转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream? Writer
是否是存文本?是!Writer。
设备:硬盘。一个文件。使用 FileWriter。
FileWriter fw = new FileWriter("SystemIn.txt");
需要提高效率,使用BufferedWriter bufw = new BufferedWriter(fw);指定编码表进行存储:
*OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");*
常用编码表:UTF-8;GBK
按照“三个明确”完成获取键盘录入并打印在控制台:
1: System.setIn(new FileInputStream("PersonDemo.java"));2: System.setOut(new PrintStream("zzz.txt"));3: //键盘的最常见写法。4: BufferedReader bufr =5: new BufferedReader(new InputStreamReader(System.in));6: BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));7: String line = null;8:9: while((line=bufr.readLine())!=null)10: {11: if("over".equals(line))12: break;13: bufw.write(line.toUpperCase());14: bufw.newLine();15: bufw.flush();16: }17: bufr.close();12)改变标准输入输出设备
System.setIn(new FileInputStream(“D:\\1.txt”));//改变标准输出设备,读取
System.setOut(new FileOutputStream(“D:\\2.txt”));//改变标准输入设备,写入
如果把标准输入输出设备都改成文件,就相当于复制文件。
通过改变标准输出流,将异常信息写入日志文件中,并且加入日志创建的时间等信息:
1: try2: {3: Date d = new Date();4: SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");5: String s = sdf.format(d);7: PrintStream ps = new PrintStream("exeception.log");8: ps.println(s);9: System.setOut(ps);12: }13: catch (IOException ex)14: {15: throw new RuntimeException("日志文件创建失败");16: }17: e.printStackTrace(System.out);
*有专门便于建立日志信息的工具,log4j*
改变输出设备还有一个应用,就是记录系统信息,Properties与流相结合。
Properties p = System.getProperties();
打印系统信息可以通过遍历p.keySet()集合来获取,也可以通过p.list(PrintStream p)方法改变输入设备,将系统信息写入日志文件存入硬盘中。
1: Properties p = System.getProperties();2: /*for(Object obj:p.keySet()){//通过遍历的方式也能获取系统信息3: System.out.println(obj+":"+p.get(obj));4: }*/5: System.out.println(p.getProperty("os.name"));6: p.list(System.out);7: p.list(new PrintStream("d:\\SystemIn.log"));8: Runtime r = Runtime.getRuntime();9: r.exec("notepad d:\\SystemIn.log");13)File类:
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false;输出流不一样,输出流对象一建立就创建文件,而且如果文件已经存在,会覆盖旧文件。boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。3,判断。
boolean exists() :文件是否存在.
isFile()://是否是文件
isDirectory();//是否是目录
isHidden();//是否隐藏
isAbsolute(); //是否是绝对路径4,获取信息。
getName():
getPath():
getParent(): //获取父目录getAbsolutePath() //绝对路径
long lastModified() //最近修改日期
long length()列出目录:
1: File dir = new File("c:\\");2: File[] files = dir.listFiles();3: for(File f : files)4: {5: System.out.println(f.getName()+"::"+f.length());6: }7:1: public static void showDir(File dir,int level)2: {3: System.out.println(getLevel(level)+dir.getName());4:5: level++;6: File[] files = dir.listFiles();7: for(int x=0; x<files.length; x++)8: {9: if(files[x].isDirectory())10: showDir(files[x],level);//递归,无条件的递归就相当于无限循环11: else12: System.out.println(getLevel(level)+files[x]);13: }14: }函数自己调用自己,称为递归。
通过list(FilenameFilter filter)列出过滤后的目录:
1: public static void listDemo_2()2: {3: File dir = new File("d:\\java");5: String[] arr = dir.list(new FilenameFilter()6: {7: public boolean accept(File dir,String name)8: {9: return name.endsWith(".java");10: }11: });12: }
删除带内容的目录:
在windows中,目录的删除时由里到外的,先删除里面的文件,再删除外面的目录。
这样就需要用到递归。
1: File[] files = dir.listFiles();3: for(int x=0; x<files.length; x++)4: {5: if(files[x].isDirectory())//递归应该有条件,否则就是无限循环6: removeDir(files[x]);7: else8: System.out.println(files[x].toString()+":-file-:"+files[x].delete());9: }14)Properties:
Properties是HashTable的子类,具有Map集合的特点,存储的是键值对。是集合中和IO相结合的容器。
Properties对象可以用作存储键值对形式的配置文件。
Properties prop = new Properties();
设置和获取元素:prop.setProperty("abc","10");prop.getProperty("abc");
15)打印流:
打印流:
能将各种类型的数据原样打印。PrintStream:
构造函数可以接收的参数类型:
1,File对象
2,字符串路径:String
3,字节输出流:OutputStream
PrintWriter:
构造函数可以接收的参数类型:
1,File对象
2,字符串路径:String
3,字节输出流:OutputStream
4,字符输出流:Writer。PrintWriter,将键盘录入数据转换为大写打印在控制台上:
1: BufferedReader bufr =2: new BufferedReader(new InputStreamReader(System.in));3: PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);4: String line = null;5: while((line=bufr.readLine())!=null)6: {7: if("over".equals(line))8: break;9: out.println(line.toUpperCase());10: //out.flush();11: }12: out.close();13: bufr.close();16)合并流:
SequenceInputStream:可以将多个流对象合并成一个流对象。
将1.txt、2.txt、3.txt这三个文件中的内容复制到4.txt这一个文件中:
1: Vector<FileInputStream> v = new Vector<FileInputStream>();2: v.add(new FileInputStream("c:\\1.txt"));3: v.add(new FileInputStream("c:\\2.txt"));4: v.add(new FileInputStream("c:\\3.txt"));5: Enumeration<FileInputStream> en = v.elements();//SequenceInputStream接受的枚举对象,集合中只有Vector有这个方法获取枚举对象6: SequenceInputStream sis = new SequenceInputStream(en);//将枚举对象作为参数传递给SequenceInputStream7: FileOutputStream fos = new FileOutputStream("c:\\4.txt");8: byte[] buf = new byte[1024];9: int len =0;10: while((len=sis.read(buf))!=-1)11: {12: fos.write(buf,0,len);13: }14: fos.close();15: sis.close();------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
本文详细介绍Java中的IO流概念,包括字符流与字节流的区别、常见异常处理方式、文件复制方法及流对象的操作规律等内容。

被折叠的 条评论
为什么被折叠?



