标签:
@author ixenos
摘要:创建文件、文件过滤、流分类、流结构、常见流、使用文件流
#当我们调用File类的构造器时,仅仅是在运行时创建了一个File对象,而不是在文件系统中创建了一个文件。File类可以表示文件系统中存在的目录或文件,也可以表示尚不存在的
#File.separator是一个跨平台的分隔符 (Win用"\",同时"\"又做反义字符,所以"\\"才表示分隔符;UNIX用"/")
1 class FileTest1{ 2 public static void main(String[] args){ 3 File testFile = new File("c:\\test"); 4 System.out.println(testFile.getAbsolutePath() + "是否存在" + testFile.exists()); 5 6 try{ 7 testFile.createNewFile(); //创建文件 8 }catch(IOException e){ 9 e.printStackTrace(); 10 } 11 12 System.out.println(testFile.getAbsolutePath() + "是否存在" + testFile.exists()); 13 14 //测试目录创建mkdirs() 15 File testDir = new File("c:\\a\\b\\c"); 16 System.out.println(testFile.getAbsolutePath() + "是否存在" + testFile.exists()); 17 18 testDir.mkdirs(); 19 System.out.println(testFile.getAbsolutePath() + "是否存在" + testFile.exists()); 20 } 21 } 22 23 ------------------------------------- 24 c:\test 是否存在:false 25 26 c:\test 是否存在:true 27 28 c:\a\b\c 是否存在:false 29 30 c:\a\b\c 是否存在:true
如果此抽象路径名不表示一个目录,那么此方法将返回 null
。否则返回一个字符串数组,每个数组元素对应目录中的每个文件或目录。
表示目录本身及其父目录的名称不包括在结果中。
每个字符串是一个文件名,而不是一条完整路径。
不保证所得数组中的相同字符串将以特定顺序出现,特别是不保证它们按字母顺序出现。
#boolean accept(File dir, String name)是FilenameFilter接口中的一个抽象方法
除了返回数组中的字符串必须满足过滤器外,此方法的行为与
方法相同。list()
如果给定 filter
为 null
,则接受所有名称。否则,当且仅当在此抽象路径名及其表示的目录中的文件名或目录名上调用过滤器的
方法返回 FilenameFilter.accept(java.io.File, java.lang.String)
true
时,该名称才满足过滤器。
*在此,可以把FilenameFileter类比成InvocationHandler,而accept就好比invoke
1 import java.io.*; 2 3 /** 4 * 面对FilenameFilter接口编程 5 */ 6 public class FileExtensionFilter implements FilenameFilter{ 7 private String extension = null; //文件拓展名 8 public FileExtensionFilter(String extension){ 9 this.extension = extension; 10 } 11 12 /** 13 * 定义过滤规则:以xxx结尾 14 * accept方法由list调用,遍历数组 15 * 形参:File dir 表示当前文件目录的File对象 16 * String name 表示当前文件名 17 */ 18 public boolean accept(File dir, String name){ 19 File tmp = new File(dir, name); 20 if(tmp.getName().toLowerCase().endWith(extension)){ 21 return true; 22 } 23 return false; 24 } 25 26 public static void main(String[] args){ 27 File currentDirectory = new File("."); 28 //构造文件过滤器对象 29 FileExtensionFilter javaFilter = new FileExtensionFilter("java"); 30 31 //list过滤符合条件的String对象,返回一个String数组(不保证有自然序) 32 String[] javaFiles = currentDirectory.list(javaFilter); 33 34 for(int i=0; i<javaFiles.length; i++){ 35 System.out.println(javaFiles[i]); 36 } 37 } 38 }
1.处理的数据单位不同,可分为:字符流,字节流
2.数据流方向不同,可分为:输入流,输出流
3.功能不同,可分为:节点流,处理流(过滤流)
根据功能分类的,可以这么理解:
节点流:节点流从一个特定的数据源读写数据。即节点流是直接操作文件,网络等的流,例如FileInputStream和FileOutputStream,他们直接从文件中读取或往文件中写入字节流。
处理流:“连接”在已存在的流(节点流或处理流)之上通过对数据的处理为程序提供更为强大的读写功能。过滤流是使用一个已经存在的输入流或输出流连接创建的,过滤流就是对节点流进行一系列的包装。例如BufferedInputStream和BufferedOutputStream,使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,以及DataInputStream和DataOutputStream,使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。他们都属于过滤流。
处理流(过滤流)采用的是装饰模式的思想,装饰模式扩展对象的功能,不同于代理模式是扩展类的功能
Java所有的流类位于java.io包中,都分别继承自以下四种抽象流类型
字节流 | 字符流 | |
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
1.继承自InputStream/OutputStream的流数据的单位都是字节(byte=8bit),如图,深色的为节点流,浅色的为处理流。
2.继承自Reader/Writer的流数据的单位都是字符(单位字符占多少字节按编码格式来算,如UTF-8),如图,深色的为节点流,浅色的为处理流。
1.节点流类型常见的有:
1)对文件操作的字节流有FileInputStream/FileOutputStream
2)对文件操作的字符流有FileReader/FileWriter
2.处理流类型常见的有:
1)缓冲流:缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率,同事增加了一些新的方法。
字节缓冲流有BufferedInputStream/BufferedOutputStream,字符缓冲流有BufferedReader/BufferedWriter,字符缓冲流分别提供了读取和写入一行的方法ReadLine和NewLine方法。
对于输出地缓冲流,写出的数据,会先写入到内存中,再使用flush方法将内存中的数据刷到硬盘。所以,在使用字符缓冲流的时候,一定要先flush,然后再close,避免数据丢失。
2)转换流:用于字节数据到字符数据之间的转换。
仅有字符流InputStreamReader/OutputStreamWriter。其中,InputStreamReader需要与InputStream“套接”,OutputStreamWriter需要与OutputStream“套接”。
3)数据流:提供了读写Java中的基本数据类型的功能。
DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,需要“套接”在InputStream和OutputStream类型的节点流之上。
4)对象流:用于直接将对象写入写出。
流类有ObjectInputStream和ObjectOutputStream,本身这两个方法没什么,但是其要写出的对象有要求,该对象必须实现Serializable接口,来声明其是可以序列化的。否则,不能用对象流读写。
5)关键字transient,由于修饰实现了Serializable接口的类内的属性,被该修饰符修饰的属性,在以对象流的方式输出的时候,该字段会被忽略。
文件读写是最常见的I/O操作,通过文件流来连接磁盘文件,读写文件内容
1.文件的读写工作流程:
1)打开文件输入流或输出流
FileInputStream实现读文件,调用FileInputStream的构造器可以打开一个文件输入流:
1 public FileInputStream(String fileName) throws FileNotFoundException //指定文件名 2 public FileInputStream(File file) throws FileNotFoundException //指定一个File对象 3 public FileInputStream(FileDescriptor fdObj) //需要一个文件描述符对象
FileDescriptor http://www.fengfly.com/plus/view-214059-1.html
如果试图在一个不存在的文件上打开一个文件输入流,该构造器将抛出异常FileNotFoundException,是IOException的子类
最常用:通过文件名打开一个文件输出流 try{FileInputStream fin = new FileInputStream("Readme.txt");} catch(IOException e) {...}
2)文件读或写操作
FileInputStream
1 public native int read() throws IOException 2 public int read(byte[] data) throws IOException 3 public int read(byte[] data, int offset, int length) throws IOException
如果由于某种原因文件不可读,read方法将抛出IOException
3)关闭文件输入流或输出流
1 ... 2 finally{ 3 try{ 4 //由于在finally模块,如果文件不存在,也就没有流,所以要有一个空指针判断 5 if(fin != null){ 6 fin.close(); 7 } 8 }catch(Exception e){} 9 } 10 ... 11 ------------------------------- 12 由于close()也可能产生异常,代码较为冗杂 13 可以使用try-with-resources来自动关闭流 http://www.cnblogs.com/ixenos/p/5701679.html
4)FileInputStream对应的FileOutputStream实现了文件输出功能
1 public FileOutputStream(String name) throws FileNotFoundException 2 public FileOutputStream(String name, boolean append) throws FileNotFoundException
(1)调用第一个构造器时,如果name指定的文件不存在,将创建该文件,并同时建立一个输出流;如果存在,那么文件的内容将被覆盖
(2)调用第二个构造器时,通过第二个参数append指定是否对已存在的文件覆盖,如果append为true,那么将在文件尾端添加新内容,如果为false,则覆盖文件内容
(3)FileOutputStream的构造器可以创建一个新文件的同时,打开一个输出流进行写入,这是File对象的createNewFile()比不了的
write public void write(byte[] b, int off, int len) throws IOException 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。write(b, off, len) 的常规协定是:将数组 b 中的某些字节按顺序写入输出流;元素 b[off] 是此操作写入的第一个字节,b[off+len-1] 是此操作写入的最后一个字节。 OutputStream 的 write 方法对每个要写出的字节调用一个参数的 write 方法。建议子类重写此方法并提供更有效的实现。 如果 b 为 null,则抛出 NullPointerException。 如果 off 为负,或 len 为负,或者 off+len 大于数组 b 的长度,则抛出 IndexOutOfBoundsException。 参数: b - 数据。 off - 数据中的初始偏移量。 len - 要写入的字节数。
write public void write(byte[] b) throws IOException 将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。 参数: b - 数据。 抛出: IOException - 如果发生 I/O 错误。
标签:
原文地址:http://www.cnblogs.com/ixenos/p/5702090.html