JAVA的I/O介绍
<<疯狂JAVA编程>>第15章有详细介绍,讲的还是相当不错的,我们可以好好看下
IO流分为输入流(InputStream)和输出流(OutputStream)两类
按流所处理的数据类型又可以分为字节流和字符流(用于处理Unicode字符数据)两类
字节流主要是由 InputStream和OutputStream作为基类,而字符流主要是由 Reader和Writer作为基类的
节点流(低级流) 和 处理流(高级流):
JAVA使用处理流来包装节点流式一种典型的装饰器设计模式,通过使用处理流来包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出功能,这就允许Java应用程序采用相同的代码,透明的方式来访问不同输入\输出设备的数据流。所以处理流也叫做包装流
下图说明相关体系:
文件类:(File):
提供文件操作功能(File可以创建,删除等操作对文件或目录,但是要访问文件内容,就必须用到输入/输出流)
1.创建File类对象:
File f;
f = new File("Test.java");
f = new File("E:\\ex\\","Test.java");
2.将目录也当作文件处理File类中提供了实现目录管理功能的方法:
File path = new File("E:\\ex\\");
File f = new File(path, "Test.java");
方法:
f.getName():返回文件名 temp.dat
f.getParent():返回文件所在目录名 data
f.getPath():返回文件路径 data\temp.dat
f.getAbsolutePath():返回绝对路径 …\data\temp.dat
f.exists():文件是否存在
f.canWrite(), f.canRead():文件是否可写、读
f.isFile(), f.isDirectory():是否为文件或目录
f.lastModified(), f.length(), f.delete():文件的最后修改日期、长度;删除文件
f.mkdir(), f.list():创建一个目录;列出目录下所有的文件
几个例子说明:
import java.io.*; class FileTest{ public static void main(String[] str){ File f = new File("E:\\Workspace\\aaa.txt"); //判断是否存在该文件 if (!f.exists()){ System.out.println("file is not exist"); try { f.createNewFile();//不存在就创建新的文件 } catch (IOException e) { e.printStackTrace(); } } File f1 = new File("E:\\Workspace\\aaa1\\sdfsdf\\asdf"); if (f1.mkdir()){ //创建目录 System.out.println("yes"); } else{ System.out.println("errors "); } } }
import java.io.*; //浏览当前目录下的所有文件和目录 class FileDirectory{ public static void main( String[] args ) { try { File f1 = new File(""); String ss = f1.getAbsolutePath(); System.out.println("ss= " + ss); File f = new File(ss); if( f.isDirectory() ) { //获取目录下所有的文件列表 File[] files = f.listFiles(); for( int i=0; i<files.length; i++ ) { if( files[ i ].isDirectory() ) { System.out.println( "<dir> " + files[ i ].getName() ); } else { System.out.println( files[ i ].getName() ); } } } } catch( Exception e ) { e.printStackTrace(); } } }
import java.io.*; class SuperTest{ public static void main(String args[]) { File dir = new File("E:\\Workspace\\Java\\test20111108"); // 用File 对象表示一个目录 Filter filter = new Filter("txt"); // 生成一个名为java的过滤器 System.out.println("list java files in directory " + dir); String[] files = dir.list(filter); // 列出目录dir下,文件后缀名为txt的所有文件 for (int i = 0; i < files.length; i++) { File f = new File(dir, files[i]); // 为目录dir 下的文件或目录创建一个File 对象 if (f.isFile()) // 如果该对象为后缀为java的文件,则打印文件名 System.out.println("file: " + f); else System.out.println("sub directory " + f); // 如果是目录则打印目录名 } } } class Filter implements FilenameFilter { String extent; Filter(String extent) { this.extent = extent; } public boolean accept(File dir, String name) { return name.endsWith("." + extent); //返回文件的后缀名 } }
字节文件流:FileInputStream和FileOutputStream
import java.io.*; /** *把一个文件的所有内容写到另外一个文件中 */ class FileStreamTest{ public static void main(String args[]) { try { File inFile=new File("test1.txt"); File outFile=new File("test2.txt"); FileInputStream fis=new FileInputStream(inFile); FileOutputStream fos=new FileOutputStream(outFile); int c; while((c=fis.read())!=-1) //读取一个字节 { fos.write(c); } fis.close(); fos.close(); }catch(FileNotFoundException e) { System.out.println("FileStreamsTest: "+e); }catch(IOException e) { System.err.println("FileStreamsTest: "+e); } } }
import java.io.*; class CopyFileTest{ public static void main(String args[]) { CopyFileTest cf = new CopyFileTest (); cf.copyFile("test1.txt","test3.txt"); } public boolean copyFile(String src,String des){ File srcFile,desFile; srcFile = new File(src); desFile = new File(des); FileInputStream fis = null; FileOutputStream fos = null; try{ desFile.createNewFile(); fis = new FileInputStream(srcFile); fos = new FileOutputStream(desFile);//覆盖 // fos = new FileOutputStream(desFile,true);//追加 int bytesRead; byte[] buf = new byte[4 * 1024]; // 4K buffer while((bytesRead=fis.read(buf))!=-1){ fos.write(buf,0,bytesRead); } fos.flush(); fos.close(); fis.close(); }catch(IOException e){ System.out.println(e); return false; } return true; } }
如果只是在尾部追加,而不是覆盖需要调用FileOutputStream(“file”,true)就Ok了,对于字符流文件就是FileWriter(“file”,true)就OK乐。
父类过滤流:
FilterInputStream(InputStream in);
FilterOutputStream(OutputStream out);
过滤流—缓冲流
类BufferedInputStream和BufferedOutputStream继承FilterInputStream和FilterOutputStream,实现了带缓冲的过滤流,它提供了缓冲机制,把任意的I/O流“捆绑”到缓冲流上,可以提高该I/O流的读取效率,在初始化时,除了要指定所连接的I/O流之外,还可以指定缓冲区的大小。
在读写的同时对数据缓存,这样避免每次读写数据都要进行实际的物理读写操作,在用BufferdOutputStream输出时,数据先输入缓冲区,当缓冲区满的时再写入连接的输出流,可以调用flush()来清空缓冲区。
import java.io.*; class SuperTest{ public static void main(String args[]) { try { File inFile = new File("test1.txt"); File outFile = new File("test4.txt"); BufferedInputStream bufFis=new BufferedInputStream(new FileInputStream(inFile),256); BufferedOutputStream bufFos=new BufferedOutputStream(new FileOutputStream(outFile),256); int len; byte bArray[]=new byte[256]; do{ System.out.println("while"); len = bufFis.read(bArray); bufFos.write(bArray,0,len); System.out.println("len: " +len); }while (len==256); bufFis.close(); bufFos.close(); } catch (FileNotFoundException e) { System.out.println("FileStreamsTest: " + e); } catch (IOException e) { System.err.println("FileStreamsTest: " + e); } } }
过滤流—数据流
DataInputStream和DataOutputStream, 继承FilterInputStream和FilterOutputStream,可以用来与计算机无关的格式读写JAVA的基本数据类型以及String对象。
readBoolean() 读一字节,非零为真
readByte() 以8位读字节
readChar() 读Unicode字符
readInt() 读整数值
writeChar(int v) 把字符写进输出流
writeLong(long v) 把长整写进输出流
writeInt(int v) 把整数写进输出流
数据输出流可以是一个已经建立好的输入数据流对象,例如网络的连结,文件等。数据流可通过如下方式建立。
FileInputStream fis = new FileInputStream("file1.txt");
FileOutputStream fos = new FileOutputStream("file2.txt");
DataInputStream dis = new DataInputStream(fis);
DataOutputStream dos = new DataOutputStream(fos);
import java.io.*; class DataStreamIOTest{ public static void main(String args[]) throws IOException { FileOutputStream fos = new FileOutputStream("a.txt"); DataOutputStream dos = new DataOutputStream(fos); try { dos.writeBoolean(true); dos.writeByte((byte) 123); dos.writeChar('J'); dos.writeDouble(3.141592654); dos.writeFloat(2.7182f); dos.writeInt(1234567890); dos.writeLong(998877665544332211L); dos.writeShort((short) 11223); } finally { dos.close(); } FileInputStream fis = new FileInputStream("a.txt"); DataInputStream dis = new DataInputStream(fis); try { System.out.println("\t " + dis.readBoolean()); System.out.println("\t " + dis.readByte()); System.out.println("\t " + dis.readChar()); System.out.println("\t " + dis.readDouble()); System.out.println("\t " + dis.readFloat()); System.out.println("\t " + dis.readInt()); System.out.println("\t " + dis.readLong()); System.out.println("\t " + dis.readShort()); } finally { dis.close(); } } }//需要注意的是必须throws IOException才可以编译通过。
字符流
例子:利用FileWriter来写文件 try { FileWriter fw = new FileWriter("mydata.txt"); PrintWriter out = new PrintWriter(fw); out.print("面朝大海,"); out.println("春暖花开!"); out.println("环境美好!!"); out.close(); fw.close(); }catch(IOException e) { e.printStackTrace(); }
例子:字符缓冲流BufferedReader import java.io.*; class SuperTest{ public static void main(String args[]) throws IOException { File file = new File("mydata.txt"); try { BufferedReader in = new BufferedReader(new FileReader(file)); String s; s = in.readLine(); while ( s != null ) { System.out.println("Read: " + s); s = in.readLine(); } in.close(); } catch (FileNotFoundException e1) { System.err.println("File not found: " + file); } catch (IOException e2) { e2.printStackTrace(); } } }
例子:拷贝(FileReader和FileWriter) try { FileReader input = new FileReader(args[0]); FileWriter output = new FileWriter(args[1]); char[] buffer = new char[128]; int charsRead; charsRead = input.read(buffer); while ( charsRead != -1 ) { output.write(buffer, 0, charsRead); charsRead = input.read(buffer); } input.close(); output.close(); } catch (IOException e) { e.printStackTrace(); } }
例子:拷贝(BufferedWriter) try { FileReader input = new FileReader(args[0]); BufferedReader bufInput = new BufferedReader(input); FileWriter output = new FileWriter(args[1]); BufferedWriter bufOutput = new BufferedWriter(output); String line; line = bufInput.readLine(); while ( line != null ) { bufOutput.write(line, 0, line.length()); bufOutput.newLine(); line = bufInput.readLine(); } bufInput.close(); bufOutput.close(); } catch (IOException e) { e.printStackTrace(); }
随机存取文件流--RandomAccessFile
1 RandomAccessFile是一种特殊的文件流,可以用它在文件的任何地方查找或者插入数据
2 RandomAccessFile同时实现了DataInput和DataOutput接口,所以可以用它来读/写文件
3构造器:
RandomAccessFile(java.io.File f,String mode)
RandomAccessFile(String file,String mode)
4 mode可以为”r”或”rw”
方法:
1 readXXX()或writeXXX():
如ReadInt(), ReadLine(), WriteChar(), WriteDouble()等
2 int skipBytes(int n):将指针向下移动若干字节
3 length():返回文件长度
4 long getFilePointer():返回指针当前位置
5 void seek(long pos):将指针调到所需位置
import java.io.*; import java.util.*; class RandomAccessFileTest{ public static void main(String args[]) { try{ File logfile=new File("mydata.txt"); if(logfile.exists()) { RandomAccessFile raf=new RandomAccessFile(logfile,"rw"); System.out.println("leghth = " + raf.length()); raf.seek(raf.length()); for(int i=0;i<5;i++) { raf.writeBytes("Write "+new Date()+ "\r\n"); } raf.seek(0); String x=raf.readLine(); while(x!=null) { System.out.println(x); x=raf.readLine(); } raf.close(); } }catch(IOException e){ e.printStackTrace(); } } }
JAVA流总结:
1 在Java中有数据传输的地方都用到I/O流(通常是文件,网络,内存和标准输入输出等)。
2 InputStream 和OutputStream是所有字节流的祖先(只有RandomAccessFile类是一个例外),read和write是它们最基本的方法,读写单位是字节
3 Reader 和Writer是所有字符流的祖先,read和write是它们最基本的方法,读写单位是字符。
4 在众多的流对象中,并不是每一种都单独使用,其中过滤流的子类在数据送出去之前做必要的处理
5 File, File(Input/Output)Stream, RandomAccessFile是处理本地文件的类。
6 Data(Input/Output)Stream是一个过滤流的子类,借此可以读写各种基本数据,在文件和网络中经常使用。如: readByte, writeBoolean等。
7 Buffered(Input/Output)Stream的作用是在数据送到目的之前先缓存,达到一定数量时再送到目的,已减少阻塞次。
8 Piped(Input/Output)Stream适合与一个处理的输出作为另一个处理的输入的情况
posted on 2013-03-22 11:08 Cynthia&Sky 阅读(7115) 评论(0) 编辑 收藏 举报