知识列表
- IO概述
- 字符流
- IO异常
- FileReader
- 复制文本文件
- BufferedWriter
- BufferedReader
- InputStream和OutputStream
- 复制图片文件
- 转换流,读取键盘录入
- 流对象操作规律
- 改变标准输入输出设备
- File类
- Properties
- 打印流
- 合并流
1)IO概述
字符流和字节流。
字节流两个基类:
InputStream?? OutputStream字符流两个基类:
Reader Writer
2)字符流
IO流是用于操作数据的,数据最常见形式是文件。
例如:在硬盘上创建一个文件并写入一些文字数据。
FileWriter:
是一个专门用于操作文件的Writer子类对象
1: class FileWriterDemo
2: {
3: public static void main(String[] args) throws IOException
4: {
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 FileWriterDemo3
2: {
3: public static void main(String[] args) throws IOException
4: {
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 FileWriterDemo2
3: {
4: public static void main(String[] args)
5: {
6: FileWriter fw = null;
7: try
8: {
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: finally
17: {
18: try
19: {
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 FileReaderDemo
2: {
3: public static void main(String[] args) throws IOException
4: {
5: //创建一个文件读取流对象,和指定名称的文件相关联。
6: //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
7: 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 FileReaderDemo2
2: {
3: public static void main(String[] args) throws IOException
4: {
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 CopyDemo
2: {
3: public static void main(String[] args) throws IOException
4: {
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: try
4: {
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: finally
22: {
23: try
24: {
25: if(fis!=null)
26: fis.close();
27: }
28: catch (IOException e)
29: {
30: throw new RuntimeException("读取关闭失败");
31: }
32: try
33: {
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: //将字节流对象转成字符流对象,使用转换流。InputStreamReader
5: //InputStreamReader isr = new InputStreamReader(in);
6:
7: //为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
8: //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: try
2: {
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: else
12: 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: else
8: 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);//将枚举对象作为参数传递给SequenceInputStream
7: 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培训、期待与您交流! -------