一、数据流的基本概念
1、理解数据流
流一般分为输入流(InputStream)和输出流(OutputStream)两类,但这种划分不是绝对的。比如一个文件,当想其中写入数据时,它就是一个输入流;当向其中读取数据时,它就是一个输出流。键盘只是一个输入流,而屏幕只是一个输出流(当然现在的触控屏,也可以完成输入)
2、java的标准数据流
标准输入输出是指在字符方式下(如DOS),程序与系统进行交互的方式分为三种:标准输入studin,对象是键盘;标准输出studio,对象是屏幕;标准错误输出stderr,对象也是屏幕。
3、字节流
从InputStream和OutputStream中派生出来的一系列类。这类流以字节byte为基本处理单位。
InputStream OutputStream
- FileInputStream/FileOutputStream
- PipedInputStream/PipedOutputStream
- ByteArrayInputStream/ByteArrayOutputStream
- FilterInputStream/FilterOutputStream
- DataInputStream/DataOutputStream
- BufferedInputStream/BufferedOutputStream
4、字符流
从Reader和Writer派生出来的一系列类,这类以16位的unicode码表示的字符为基本处理单位。
Reader、Writer
- InputStreamReader、OutputStreamWriter
- FileReader、FileWriter
- CharArrayReader、CharArrayWriter
- PipedReader、PipedWriter
- FilterReader、FilterWriter
- BufferedReader、BufferedWriter
- StringReader、StringWriter
二、字节流初步
InputStream和OutputStream有如下方法:
read():从流中读入数据
skip():跳过流中若干字节数
available():返回流中可用字节数
mark():在流中标记一个位置
reset():返回标记过的位置
markSupport():是否支持标记和复位操作
close():关闭流
/**
* 每次在源文件中读取512个字节,存储在缓冲区buffer中,再将以buffer中的值构造的子串new String(buffer)输出
* 1、创建文件输入流对象FileInputStream
* 2、定义每次读取的长度 int len以字节为单位
* 3、定义缓冲区byte[] buffer=new byte[len];
* 4、循环读取while(判定条件:){......}
*/
public class OpenFile {
public static void main(String[] args)throws IOException{
try{
//创建文件输入流对象
FileInputStream rf=new FileInputStream("D:\\openfile.java");
//定义每次读取的长度
int len=512;
//定义缓存数组
byte[] buffer=new byte[len];
while((rf.read(buffer, 0, len))!=-1&&(len>0)){
System.out.print(new String(buffer));
}
System.out.println();
//关闭流
rf.close();
}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 从键盘输入一行数据,存储在缓冲区buffer中,在以OutputStream的write()方法,将buffer中内容写入WriteFile.txt中
* 1、定义缓冲区长度和输入字符长度
* 2、System.in.read(buffer)读取输入的值,并放在缓冲区buffer中
* 3、创建输出流对象
* 4、写入输出流
* 5、关闭输出流
*/
public class WriteFile {
public static void main(String[] args){
try{
System.out.print("input:");
int count,len=512;
byte[] buffer=new byte[len];
count=System.in.read(buffer);
//创建文件输出流对象
FileOutputStream wf=new FileOutputStream("D:\\WriteFile.txt");
//写入输出流
wf.write(buffer,0,count);
//关闭流
wf.close();
System.out.println("save to writefile.txt!");
}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
}
三、文件操作
1、构造方法
public File(String pathname)
public File(File patent,String chile)
public File(String patent,String child)
public File(File patent,String chile)
public File(String patent,String child)
2、文件名的处理
String getName( ); //得到一个文件的名称(不包括路径)
String getPath( ); //得到一个文件的路径名
String getAbsolutePath( );//得到一个文件的绝对路径名
String getParent( ); //得到一个文件的上一级目录名
String renameTo(File newName); //将当前文件名更名为给定文件的完整路径
String getPath( ); //得到一个文件的路径名
String getAbsolutePath( );//得到一个文件的绝对路径名
String getParent( ); //得到一个文件的上一级目录名
String renameTo(File newName); //将当前文件名更名为给定文件的完整路径
3、文件属性测试
boolean exists( ); //测试当前File对象所指示的文件是否存在
boolean canWrite( );//测试当前文件是否可写
boolean canRead( );//测试当前文件是否可读
boolean isFile( ); //测试当前文件是否是文件(不是目录)
boolean isDirectory( ); //测试当前文件是否是目录
boolean canWrite( );//测试当前文件是否可写
boolean canRead( );//测试当前文件是否可读
boolean isFile( ); //测试当前文件是否是文件(不是目录)
boolean isDirectory( ); //测试当前文件是否是目录
4、普通文件信息和工具
long lastModified( );//得到文件最近一次修改的时间
long length( ); //得到文件的长度,以字节为单位
boolean delete( ); //删除当前文件
long length( ); //得到文件的长度,以字节为单位
boolean delete( ); //删除当前文件
5、目录操作
boolean mkdir( ); //根据当前对象生成一个由该对象指定的路径
String list( ); //列出当前目录下的文件
String list( ); //列出当前目录下的文件
/**
* 自动复制文件的操作
* @author chanxiaoxi
*/
public class UpdateFile {
public static void main(String[] args)throws IOException{
String fname="WriteFile.txt";
String childdir="backup";
new UpdateFile().update(fname,childdir);
}
/**
* 更新文件
* @param fname
* @param childdir
* @throws IOException
*/
public void update(String fname,String childdir)throws IOException{
File f1,f2,child;
//在D盘中创建文件对象f1
f1=new File("D:\\"+fname);
//当D盘中创建文件对象childdir
child=new File("D:\\"+childdir);
if(f1.exists()){
if(!child.exists()){//如果child不存在
child.mkdir();//根据当前对象生成一个由该对象指定的路径
f2=new File(child,fname);//在子目录总创建f2
if(!f2.exists()||f2.exists()&&(f1.lastModified()>f2.lastModified()))
copy(f1,f2);
getinfo(f1);
getinfo(f2);
}
}else{
System.out.println(f1.getName()+"——file not found");
}
}
/**
* 复制文件操作
* @param f1
* @param f2
* @throws IOException
*/
public void copy(File f1,File f2)throws IOException{
//创建文件输入流对象
FileInputStream rf=new FileInputStream(f1);
FileOutputStream wf=new FileOutputStream(f2);
//创建文件输出流对象
int count,len=512;
byte[] buffer=new byte[len];
//读取输入流
count=rf.read(buffer, 0, len);
while(count!=-1){
//写入输出流
wf.write(buffer,0,count);
count=rf.read(buffer,0,len);
}
System.out.println("CopyFile:"+f2.getName());
rf.close();
wf.close();
}
/**
* 获取文件信息
* @param f1
* @throws IOException
*/
public static void getinfo(File f1)throws IOException{
SimpleDateFormat df;
df=new SimpleDateFormat("yyyy年MM月dd日hh时mm分");
if(f1.isFile()){
System.out.println("<FILE>\t"+f1.getAbsolutePath()+"\t"
+f1.length()+"\t"+df.format(new Date(f1.lastModified())));
}else{
System.out.println("\t"+f1.getAbsolutePath());
File[] files=f1.listFiles();
for(int i=0;i<files.length;i++)
getinfo(files[i]);
}
}
}
五、文件过滤器
类FilterInputStream和FilterOutputStream分别对其他输入输出流进行特殊处理,他们在读/写数据的同时,可以对数据进行特殊处理。另外还提供了同步机制,使得某一时刻只有一个输入/输出流
类FilterInputStream和FilterOutputStream分别重写了父类InputStream和OutputStream的所有方法,同时他们的子类也应该重写他们的方法以满足特殊的需要。