Lesson 2

来源:互联网 发布:mac怎么设置新浪邮箱 编辑:程序博客网 时间:2024/04/29 01:34

把号码写入指定的记事本中

 

知识点:

         1、File

         2、BufferedWriter

         3、FileWriter

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

 

一、java的FILE类用法整理

Java文件操作我个人认为重要的问题有:

a:如何跨平台问题
b:文件编码问题,尤其是多语言平台情况下如何正常工作。
c:文件读写效率、操作效率
d:文件加密和文件安全
e:文件快速检索,强烈建议使用lence进行文件检索及文件管理。

以下是本人做的一些整理:

一:建立文件

File file1 = new File ("C://temp//myNote.txt"); // in Windows 这是windows文件系统下的方法
File file2 = new File ("/tmp/myNote.txt"); // in Linux/Unix unix文件系统的方法

最安全的建立文件的方法:

File myFile = new File("C:" + File.separator + "jdk1.5.0" + File.separator, "File.java");

File.separator 是文件路径符号。
System.out.println(myFile.getName());//取得文件名称的方法
System.out.println(myFile.getPath());//取得文件路径的方法
System.out.println(myFile.isAbsolute());//判断文件是否完整
System.out.println(myFile.getParent());//取得文件的根目录
System.out.println(myFile.exists());//判断文件是否存在
System.out.println(myFile.isDirectory());//判断是否是目录
System.out.println(myFile.isFile());//判断是否是文件
System.out.println(myFile.isHidden());//判断是否是隐藏文件
System.out.println(myFile.canRead());//判断是否可读
System.out.println(myFile.canWrite());//判断是否可写

File myFile_A = new File("C:" + File.separator);
for(String s: myFile_A.list()){//读取某个目录下所有文件
System.out.println(s);
}

File myFile_C=new File("d:/test.txt");
System.out.println(new Date(myFile_C.lastModified()));//最后一次编辑时间
myFile_C.renameTo(new File("c:/text.txt.bak"));//从命名
myFile_C.setReadOnly();//设置为只读
二:文件过滤方法

java提供了很好的文件过滤借口:FilenameFilter 过滤以后的文件可以用listFiles显示出来。效率还是非常高的。

import java.io.File;
import java.io.FilenameFilter;
import java.util.Date;
/**
* 文件过滤器过滤类
* @author zeu
*/
class FileListFilter implements FilenameFilter {
private String name;
private String extension;
public FileListFilter(String name, String extension) {
this.name = name;
this.extension = extension;
}
public boolean accept(File directory, String filename) {
boolean fileOK = true;
if (name != null) {
fileOK = filename.startsWith(name);
}
if (extension != null) {
fileOK = filename.endsWith('.' + extension);
}
return fileOK;
}
}
测试方法:

import java.io.File;
import java.io.FilenameFilter;
import java.util.Date;
/**
* 文件过滤器 运行函数
* @author zeu
*/
public class Run_FileListFilter {
public static void main(String[] args) {
File myDir = new File("d:/");
FilenameFilter select = new FileListFilter("F", "txt");
File[] contents = myDir.listFiles(select);
for (File file : contents) {
System.out.println(file + " is a " + (file.isDirectory() ? "directory" : "file")
+ " last modified on/n" + new Date(file.lastModified()));
}
}
}
三:建立目录、文件、临时文件、删除文件或目录
import java.io.File;
import java.io.IOException;

public class MakeDir {

public static void main(String[] args) {
File myFile=new File("D:/myFubin/");
if(myFile.mkdir()){//单级目录
System.out.println("建立目录成功");
}else{
System.out.println("建立目录失败");
}

File myFile_A=new File("D:/myFubin/test/");
if(myFile_A.mkdirs()){//多级目录
System.out.println("建立目录成功");
}else{
System.out.println("建立目录失败");
}

File file = new File("d://myFubin//test.txt");
try {
file.createNewFile();//建立空文件
} catch (IOException e) {
e.printStackTrace();
}

System.out.println(file.canRead());

if(file.delete()){//删除文件或删除目录
//删除文件的另外一个方法:file.deleteOnExit() 这种方法是在程序退出的时候将文件删除
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}

try {
File tmp = File.createTempFile("foo", "tmp");//建立临时文件
System.out.println("刚才建立的临时文件在:" + tmp.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}

 


}

}

范例:

/*
java.io.File
public class File extends Object implements Serializable, Comparable


◇ 文件或目录的生成

  public File(String path);//如果path是实际存在的路径,则该File对象表示的是目录;
         //如果path是文件名,则该File对象表示的是文件。
  public File(String path,String name);path是路径名,name是文件名
  public File(File dir,String name);dir是路径名,name是文件名

 ◇ 文件名的处理

  String getName( ); //得到一个文件的名称(不包括路径)
  String getPath( ); //得到一个文件的路径名
  String getAbsolutePath( );//得到一个文件的绝对路径名
  String getParent( ); //得到一个文件的上一级目录名
  String renameTo(File newName); //将当前文件名更名为给定文件的
                  //完整路径

 ◇ 文件属性测试

  boolean exists( ); //测试当前File对象所指示的文件是否存在
  boolean canWrite( );//测试当前文件是否可写
  boolean canRead( );//测试当前文件是否可读
  boolean isFile( ); //测试当前文件是否是文件(不是目录)
  boolean isDirectory( ); //测试当前文件是否是目录

 ◇ 普通文件信息和工具

  long lastModified( );//得到文件最近一次修改的时间
  long length( ); //得到文件的长度,以字节为单位
  boolean delete( ); //删除当前文件

 ◇ 目录操作

  boolean mkdir( ); //根据当前对象生成一个由该对象指定的路径
  String list( ); //列出当前目录下的文件


*/

 

二、FileWriter

JAVA基础IO介绍

wilder

本文主要翻译自sun的tutotrial文档,详细内容请参见英文原文

 

一个I/O流表示一个输出源一个输入目的地,流可以处理多种类型的数据源/数据目标:如文件,设备,其它程序甚至内存数组.
 
流支持多种不同类型的数据,包括简单的byte,原始数据单位,本地字符串以及对象,一些流只是简单传递数据,一些可以使用有效的手段做一些转换处理
 

不用关心它们内部如何实现,所有的流对于程序来讲表现相同的模式:流是一序列的数据,程序使用输入流从源头读取数据,如下面所示:

 
程序使用输出流向目标写入数据,如下面所示:

在本文中我们将看到使用流操纵各种不同的数据,从原始数据到高级对象.

上图中的数据源和数据目标可以是任何数据,这当然包括磁盘文件,并且可以是其它程序,外围设备,网络套接字或数组,在接下来的章节中我们将使用最基础的字节流byte流来展示一些基础的io操作,比如说输入,我们会用一个示例文件 它的内容如下:

 

In Xanadu did Kubla Khan
A stately pleasure
-dome decree:
Where Alph, the sacred river, ran
Through caverns measureless to man
Down to a sunless sea.

 

In Xanadu did Kubla Khan

A stately pleasure-dome decree:

Where Alph, the sacred river, ran

Through caverns measureless to man

Down to a sunless sea.

 

 
这里使用字节流来处理输入输出8bit的字节,这些字节流类都从InputStream和OutputStream继承下来.
因为有好几种字节流类,为了展示字节流类如何工作,我们主要看一下文件io流FileInputStream和FileOutputStream,其它的字节流工作方式相同,不同的地方主要是建造方式不一样.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyBytes {
    
public static void main(String[] args) throws IOException {
        FileInputStream in 
= null;
        FileOutputStream out 
= null;
        
try {
            in 
= new FileInputStream("xanadu.txt");
            out 
= new FileOutputStream("outagain.txt");
            
int c;

            
while ((c = in.read()) != -1{
                out.write(c);
            }


        }
 finally {
            
if (in != null{
                in.close();
            }

            
if (out != null{
                out.close();
            }

        }

    }

}


  

 

注意read() 方法返回整数值,如果-1表示已经读取到了流的结束
注意流使用完了一定要关闭,否则引起很严重的资源泄露.
下面来看一下使用字符流CharacterStream,
在java平台中,存贮字符数据使用unicode编码,字符流自动的使用这一格式转换,从数据读取或写出,自动将unicode编码转换成本地字符集,在西方本地字符集通常是8个bit ASCII超集
在大部分程序中,使用字符流没有使用字节流复杂,输入输出流类自动的将数据转换成本地字符集,一个程序使用字符流代替字节流可以自动的转换适应到本地字符集适应国际化的需要,所有的工作不需要额外的编码工作.
 
字符流类都是从Reader,Writer继承过来的,同字节流一样,我们看一下文件操作的字符流

 

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyCharacters {
    
public static void main(String[] args) throws IOException {
        FileReader inputStream 
= null;
        FileWriter outputStream 
= null;

        
try {
            inputStream 
= new FileReader("xanadu.txt");
            outputStream 
= new FileWriter("characteroutput.txt");

            
int c;
            
while ((c = inputStream.read()) != -1{
                outputStream.write(c);
            }

        }
 finally {
            
if (inputStream != null{
                inputStream.close();
            }

            
if (outputStream != null{
                outputStream.close();
            }

        }

    }

}


 

和上一个例子差不多,只不过这里使用的是FileReader和FileWriter,而前者使用的是FileInputStream和FileOutputStream,值得注意的是两个例子都是将数据读到一个int变量中,但是这里,此int变量的最后16个bite存放的是一个character数据,而前者int变量最后8bit存放的是一个byte
字符流经常被包装成字节流使用
InputStreamReader,OutputStreamWriter
 
行为导向的字符流
经常处理文本时,是一行一行的处理
这时我们使用BufferRreader, PrintWriter
 
缓冲流
大部分例子我们看到的是使用无缓冲的io操作,这意味着每一个读写都是直接handled到操作系统,没有延迟的.这些使得程序变得非常低效,因为每一个请求经常会触发磁盘访问,网络激活及其它相当费时的操作开销.
为了减少这种开销,java实现了缓存io流,从内存读写的流.读取时当内存为空时者才会触发本地调用,写入时,只有当内存满了之后才会触发本地调用,程序可以将一个非缓冲的流包装成一个缓冲的流,在上面例子中我们经常使用的BufferedReader, BufferedWriter
这里有四种类型的缓冲流
BufferedInputStream/BufferedOutputStream
BufferedReader/BufferedWriter
后面主要针对字符流
缓存的冲洗 Flush Buffered Stream
经常因为某些原因我们不会等到buffer full才把数据同步到设备(文件,网络等)
这时我们 需要做flush操作
一些缓冲流支持自动冲洗,只需要指定一个可选的构造参数,当自动冲洗被激活时,一些特定的事件会触发缓冲流的冲洗,如PrinterWtriter缓冲流在每次调用println或format时
如果手工冲洗,调用flush就行了这个方法在每一个流上都有,但是只有缓冲流才会有效果.
BufferedWriter

FileReader和FileWriter

如果想要存取的是一个文本文件,可以直接使用java.io.FileReader和java.io.FileWriter类,它们分别继承自InputStreamReader与OutputStreamWriter。可以直接指定文件名称或File对象来打开指定的文本文件,并读入流转换后的字符,字符的转换会根据系统默认的编码(若要指定编码,则还是使用InputStreamReader与OutputStreamWriter)。

FileReader和FileWriter的使用非常简单,下面举个例子。在Linux下编写的文本文件,其断行字符是/n,而在Windows下编写的文本文件其断行是/r与/n两个连续字符。如果在Windows下使用记事本打开一个Linux下编写的文本文件,其在显示上并不会有断行的效果,且/n字符会被用一个黑色方块来显示。

范例14.18是一个简单的程序,可以读入Linux下编写的文本文件,再写入另一个文件。在读取过程中若遇到/n字符,就取代为/r与/n两个连续字符,这样新的文件在Windows的记事本程序中,就可以有断行显示的效果。

范例14.18  FileReaderWriterDemo.java

package onlyfun.caterpillar;

import java.io.*;

public class FileReaderWriterDemo {
public static void main(String[] args) {
try {
FileReader fileReader =
new FileReader(args[0]);
FileWriter fileWriter =
new FileWriter(args[0] + ".txt");

int in = 0;
char[] wlnChar = {'/r', '/n'};
while((in = fileReader.read()) != -1) {
if(in == '/n') {
// 写入"/r/n"
fileWriter.write(wlnChar);
}
else
fileWriter.write(in);
}
fileReader.close();
fileWriter.close();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("请指定文件");
}
catch(IOException e) {
e.printStackTrace();
}
}
}

三、

 

BufferedReader和BufferedWriter

java.io.BufferedReader与java.io.BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出至目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。例如一个文件,通过缓冲区可减少对硬盘的输入/输出动作,以提高文件存取的效率。

之前在介绍取得用户输入时,就使用过BufferedReader。从标准输入流System.in中直接读取用户输入时,用户每输入一个字符,System.in就读取一个字符。为了能一次读取一行用户的输入,使用了BufferedReader来对用户输入的字符进行缓冲。readLine()方法会在读取到用户的换行字符时,再一次将整行字符串传入。

System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能。例如:

BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));

范例14.19示范了BufferedReader与BufferedWriter的使用。可以在文字模式下输入字符,程序会将输入的文字存储至指定的文件中,如果要结束程序,输入quit字符串即可。

范例14.19  BufferedReaderWriterDemo.java

package onlyfun.caterpillar;
import java.io.*;
public class BufferedReaderWriterDemo {
public static void main(String[] args) {
try {
// 缓冲System.in输入流
BufferedReader bufReader =
new BufferedReader(
new InputStreamReader(System.in));
// 缓冲FileWriter字符输出流
BufferedWriter bufWriter =
new BufferedWriter(new FileWriter(args[0]));
            String input = null;
            // 每读一行进行一次写入动作
while(!(input =
bufReader.readLine()).equals("quit")) {
bufWriter.write(keyin);
// newLine()方法写入与操作系统相依的换行字符
bufWriter.newLine();
}
            bufReader.close();
bufWriter.close();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("没有指定文件");
}
catch(IOException e) {
e.printStackTrace();
}
}
}

由于换行字符依操作系统不同而有所区别,在Windows下是/r/n,在Linux下是/n,在Mac OS下是/r,您可以使用newLine()方法,由执行环境依当时的操作系统决定该输出哪一种换行字符

 

 很明显bufferedreader的用法比inputstream要复杂,复杂的存在必然会导致优势的存在!我们都知道inputstream是一个字节一个字节的读取,每次读取都会执行一次IO,我们知道io的操作是很费时间的,这就必然会导致程序的效率,而bufferedreader很好的解决这一问题,它可以一次读取大量的数据,大大减少了io次数,效率也就上去了,这就像有辆能乘坐一百人的大巴,从热力输送学生到理工本部,司机脑残,学生没睡醒,非要一次只坐一个同学,大巴的来回跑一百趟才能把这一百人全部送到学校,这就类似inputstream,另一个司机是清华毕业,智商当然高了,他让这一百人全部上车,一次九ok了,虽然在学生上车时多用了点时间,但总时间要远比那个脑残司机要少的多!!!当然在计算机中不会有这么大的时间差!!哔哔了这么多,应该表述清楚了,下面是一个bufferedreader的例子,本想写个关于bufferedreader比inputstream快的例子,可能是本人人品太好了吧,运行的结果每次都是0毫秒~~~

package cn.tsp2s.liu.liubao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Administrator
 */
public class TestBufferedReader {
    public static void main(String[] args){
        FileReader in=null;
        BufferedReader read=null;
        String s=null;
        BufferedWriter writer=null;
        try {
            in = new FileReader("d://java//TestLeap.java");
            read=new BufferedReader(in);
            writer=new BufferedWriter(new FileWriter("d://java//leap.txt"));
            while ((s = read.readLine()) != null) {
               // System.out.println(s);
                writer.write(s);
                //这里调用newline()方法是让它输出和读取的完全一致,理由不解释
                writer.newLine();
                //这里一定要调用flush()方法,如果不调用,文件中将会显示不全或者压根就不显示任何东西,理由不解释,你肯定知道
                writer.flush();    
            }
        } catch (FileNotFoundException ex) {
            System.out.println("找不到指定文件!!");
        }catch (IOException e) {
            System.out.println("文件读取有误!");
        }finally{
            try {
                writer.close();
                read.close();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
    }
}