黑马程序员---IO流及File类
2015-06-26 19:40
495 查看
一、IO流
概念:
流是一组有序的数据序列,依据操作的类型,可以分为输入流和输出流两种。注:
所有输入流都是抽象类Reader或抽象类InputStream的子类;
所有输出流都是抽象类Writer或抽象类OutputStream的子类;
输入流:
字节流:InputStream类,其常用方法如下:void close() 关闭此输入流并释放与该流关联的所有系统资源。 void mark(int readlimit) 在此输入流中标记当前的位置。 boolean markSupported() 测试此输入流是否支持 mark 和 reset 方法。 abstract int read() 从输入流中读取数据的下一个字节。 int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。 int read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组。 void reset() 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 long skip(long n) 跳过和丢弃此输入流中数据的 n 个字节。
字符流:Reader类为Java中专门用于处理字节的,Java得字符用的是Unicode编码,双字节。其常用方法如下:
abstract void close() 关闭该流并释放与之关联的所有资源。 void mark(int readAheadLimit) 标记流中的当前位置。 boolean markSupported() 判断此流是否支持 mark() 操作。 int read() 读取单个字符。 int read(char[] cbuf) 将字符读入数组。 abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。 int read(CharBuffer target) 试图将字符读入指定的字符缓冲区。 boolean ready() 判断是否准备读取此流。 void reset() 重置该流。 long skip(long n) 跳过字符。
输出流:
字节流:OutputStream类,其常用方法如下:void close() 关闭此输出流并释放与此流有关的所有系统资源。 void flush() 刷新此输出流并强制写出所有缓冲的输出字节。 void write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。 void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 abstract void write(int b) 将指定的字节写入此输出流。
字符流:Writer类,其常用方法如下:
Writer append(char c) 将指定字符添加到此 writer。 Writer append(CharSequence csq) 将指定字符序列添加到此 writer。 Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列添加到此 writer.Appendable。 abstract void close() 关闭此流,但要先刷新它。 abstract void flush() 刷新该流的缓冲。 void write(char[] cbuf) 写入字符数组。 abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 void write(int c) 写入单个字符。 void write(String str) 写入字符串。 void write(String str, int off, int len) 写入字符串的某一部分。
二、缓冲区
目的:
缓冲区的出现是为了提高对数据的读写效率。临时存储数据,达到一定数量后一起处理。实现类有以下四种:BufferedInputStream类,BufferedOutputStream类,BufferedWriter类和BufferReadered类。特有方法:
readLine()方法:一次读取一行。返回包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null。只返回回车符之前的内容,不返回回车符。例如,
String line = null; while((line=bufr.readLine())!= null) { System.out.println (line); }该缓冲区提供了一次读一行的方法readLine(),方便了对文本数据的读取。
readLine()原理:
无论是读一行还是读取多个字符,都是在硬盘上逐个读取。最终使用的是read()方法,一次读取一个。将字符临时 存到内部数组,遇到换行符不存,将之前的字符变成字符串返回,换行符相当于停止标识。代码如下:
public String myReadLine() throws IOException//readLine的原理 { StringBuilder sb = new StringBuilder();//建立容器,存放字符。 int ch = 0; while((ch=fr.read())!=-1) { if(ch=='\r')//换行符不能读取 continue; if(ch=='\n') return sb.toString(); else sb.append((char)ch); } if(sb.length()!=0)//防止最后一行因为没有换行符而无法输出。 return sb.toString(); return null; }
装饰设计模式
readLine()方法调用了read()方法,同时增强了read()方法的功能。将被增强的对象传给增强类,增强类提供更强的方法。所以,MyBufferedReader是对BufferedReader的增强。这种模式就是“装饰设计模式”。当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有类,并提供加强功能,那么这个自定义的类称为“装饰类”。
特点:
会通过构造函数接受被装饰的对象,并基于被装饰的对象的功能,提供增强功能。
package com.itheima; import java.io.*; public class MyLineBufferReaderDemo { public static void main(String[] args) { // TODO 自动生成的方法存根 MyLineBufferedReader myDemo=null; try { myDemo = new MyLineBufferedReader(new FileReader("D:\\HaxLogs1.txt")); String str=null; while((str=myDemo.readLine())!=null) { System.out.println(myDemo.getNum()+":"+str); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { try { myDemo.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } } class MyLineBufferedReader extends Reader { private Reader in; public MyLineBufferedReader(Reader in) { // TODO 自动生成的构造函数存根 this.in = in; } private int num =1; public int getNum() { return num; } public String readLine()throws IOException { StringBuilder sb = new StringBuilder(); int ch; while((ch=in.read())!=-1) { if(ch=='\r') continue; if(ch=='\n') { num++; return sb.toString(); } sb.append((char)ch); } return null; } public void setLineNum(int num) { this.num = num; } public void close() throws IOException { // TODO 自动生成的方法存根 in.close(); } public int read(char[] cbuf, int off, int len) throws IOException { // TODO 自动生成的方法存根 return in.read(cbuf, off, len); } }
优点:
1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
LineNumberReader类(装饰类)
getLineNumber(),获得行号,默认从1开始。返回的是读取的这一行的行号。
setLineNumber(),设置行号,从多少开始。
继承了BufferedReader类,属于这个体系,增强了行号的功能。
键盘录入
字段摘要
static PrintStream err “标准”错误输出流。 static InputStream in “标准”输入流。 static PrintStream out “标准”输出流。
复制文件的小Demo:
package com.itheima; import java.io.FileReader; import java.io.FileWriter; public class CopyDemo { public static void main(String[] args) { // TODO 自动生成的方法存根 FileWriter fileWriter = null; FileReader fileReader = null; try { fileReader = new FileReader("D:\\HaxLogs1.txt"); fileWriter = new FileWriter("D:\\HaxLogs2.txt",true); char[] ch = new char[1024]; int len; while((len = fileReader.read(ch))!=-1) { fileWriter.write(ch,0,len); fileWriter.flush(); } } catch (Exception e) { // TODO: handle exception } finally { try { if(fileReader != null) fileReader.close(); if(fileWriter!= null) fileWriter.close(); } catch (Exception e2) { // TODO: handle exception } } } }
编码表:
按照指定的编码表(UTF-8或者GBK),将录入的数据存入指定文件中
平时的读写使用默认的字符编码表,即系统的编码,GBK。转换流可以指定编码表,这也是转换流存在的重要原因,不仅仅是调用readLine()和newLine()。也就是说,只要是涉及到字符编码转换,就需要使用转换流。
使用不同的编码表,占用的空间不同。再就是,FileReader和FileWriter,默认GBK编码,无法处理UTF-8编码,需要使用转换流才能读取。转换流是以上两类的父类,具有使用多种编码的功能。依照文件的编码来确定使用何种数据处理类:GBK使用FileReader,UTF-8使用InputStreamReader。使用转换流更加广泛,但需要传入字节流,FileReader更加简便。
三、File类
解释:File类是java.io包中唯一代表磁盘文件本身的对象。
构造方法:
1. File(String pathname);
2. File(String parent,String child)
3. File(File f,String child)
File类常用方法:
boolean canExecute() 测试应用程序是否可以执行此抽象路径名表示的文件。 boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。 boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。 int compareTo(File pathname) 按字母顺序比较两个抽象路径名。 boolean createNewFile() 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。 static File createTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。 static File createTempFile(String prefix, String suffix, File directory) 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。 boolean delete() 删除此抽象路径名表示的文件或目录。 void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。 boolean equals(Object obj) 测试此抽象路径名与给定对象是否相等。 boolean exists() 测试此抽象路径名表示的文件或目录是否存在。 File getAbsoluteFile() 返回此抽象路径名的绝对路径名形式。 String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。 File getCanonicalFile() 返回此抽象路径名的规范形式。 String getCanonicalPath() 返回此抽象路径名的规范路径名字符串。 long getFreeSpace() 返回此抽象路径名指定的分区中未分配的字节数。 String getName() 返回由此抽象路径名表示的文件或目录的名称。 String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null 。 File getParentFile() 返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null 。 String getPath() 将此抽象路径名转换为一个路径名字符串。 long getTotalSpace() 返回此抽象路径名指定的分区大小。 long getUsableSpace() 返回此抽象路径名指定的分区上可用于此虚拟机的字节数。 int hashCode() 计算此抽象路径名的哈希码。 boolean isAbsolute() 测试此抽象路径名是否为绝对路径名。 boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。 boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。 boolean isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件。 long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。 long length() 返回由此抽象路径名表示的文件的长度。 String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。 String[] list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。 File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 File[] listFiles(FileFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。 File[] listFiles(FilenameFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。 static File[] listRoots() 列出可用的文件系统根。 boolean mkdir() 创建此抽象路径名指定的目录。 boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。 boolean setExecutable(boolean executable) 设置此抽象路径名所有者执行权限的一个便捷方法。 boolean setExecutable(boolean executable, boolean ownerOnly) 设置此抽象路径名的所有者或所有用户的执行权限。 boolean setLastModified(long time) 设置此抽象路径名指定的文件或目录的最后一次修改时间。 boolean setReadable(boolean readable) 设置此抽象路径名所有者读权限的一个便捷方法。 boolean setReadable(boolean readable, boolean ownerOnly) 设置此抽象路径名的所有者或所有用户的读权限。 boolean setReadOnly() 标记此抽象路径名指定的文件或目录,从而只能对其进行读操作。 boolean setWritable(boolean writable) 设置此抽象路径名所有者写权限的一个便捷方法。 boolean setWritable(boolean writable, boolean ownerOnly) 设置此抽象路径名的所有者或所有用户的写权限。 String toString() 返回此抽象路径名的路径名字符串。 URI toURI() 构造一个表示此抽象路径名的 file: URI。
示例:
package com.itheima;
import java.io.File;
public class FileTest{
<span style="white-space:pre"> </span>public static void main(String[] args){
<span style="white-space:pre"> </span>File file = new File("word.txt");
<span style="white-space:pre"> </span>if(file.exists()){
<span style="white-space:pre"> </span>String name = file.getName();
<span style="white-space:pre"> </span>long length = file.length();
<span style="white-space:pre"> </span>boolean hidden = file.isHidden();
<span style="white-space:pre"> </span>String absolutepath = file.getAbsolutePath();
<span style="white-space:pre"> </span>System.out.println("文件名为:"+name);
<span style="white-space:pre"> </span>System.out.println("文件长度为:"+length);
<span style="white-space:pre"> </span>System.out.println("文件的绝对路径为:"+absolutepath);
<span style="white-space:pre"> </span>System.out.println("文件是否隐藏:"+hidden);
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>System.out.println("文件不存在");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
} System.out.println(");")}
}
递归
:函数自己调用自己。这种编程模式称为“递归”。
注意:
1. 必须有限定条件,保证函数能够结束。
2. 小心递归的次数,尽量避免内存溢出。
递归原理:按照正常顺序依次执行,只是某些语句由函数代替,需要先将函数内的语句执行完毕才能继续向下执行。
举例
public void printJavaOfFolder(String folderName) { //打印文件夹中后缀名为.java的文件 File file = new File(folderName); String[] filename= file.list(); for(String str:filename) { if(new File(folderName,str).isDirectory()) //通过递归方式获取下层文件夹中的文件夹 printJavaOfFolder(folderName+"\\"+str); if(str.matches("\\w+\\.java")) { if(!(new File(folderName,str).isDirectory())) //剔除掉后缀名为.java的文件夹 System.out.println(folderName+"\\"+str); } } }
Properties类
是HashTable的子类,具备了Map集合的特点,里面存储的键值对都是字符串。
加载信息时需要有固定格式:键=值。
常见方法
1. 获取、设置
setProperty(String key, String value);设置键值对,也可以通过覆盖重新设置值。 String getProperty(String key),通过键获得值 Set<String> stringPropertyNames(),返回一个Set<String>集合,通过遍历获得值。1.6以后出现。
2. 将文本文件中的键值对存到集合中进行操作。
步骤:1. 用一个流和文件关联。2. 读取一行数据,将该行数据用“=”切割。3. 等号右边为键,左边为值,存入集合中。例如,
3. 字节输出流,OutputStream。
相关文章推荐
- sql2005 附加数据库出错(错误号:5123)解决方法
- C#中File类的文件操作方法详解
- asp #include file 与 #include virtual 的区别小结第1/2页
- PHP file_exists问题杂谈
- css美化input file按钮的代码方法
- 改变文件域的样式实现思路同时兼容ie、firefox
- How to Auto Include a Javascript File
- 清理SQL Server 2008日志文件Cannot shrink log file 2 的解决方案
- Locate a File Using a File Open Dialog Box
- Save a File Using a File Save Dialog Box
- 基于java file 文件操作operate file of java的应用
- php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
- PHP 得到根目录的 __FILE__ 常量
- 解析php dirname()与__FILE__常量的应用
- file_get_contents获取不到网页内容的解决方法
- sql2005 create file遇到操作系统错误5拒绝访问 错误1802
- Can’t open file:'[Table]mytable.MYI'
- js 获取、清空input type="file"的值示例代码
- PHP 的 __FILE__ 常量
- 将input file的选择的文件清空的两种解决方案