33.JAVA编程思想——JAVA IO File类

RandomAccessFile用于包括了已知长度记录的文件。以便我们能用 seek()从一条记录移至还有一条;然后读取或改动那些记录。

各记录的长度并不一定同样;仅仅要知道它们有多大以及置于文件何处就可以。

首先。我们有点难以相信RandomAccessFile 不属于InputStream 或者OutputStream 分层结构的一部分。除了恰巧实现了DataInput 以及DataOutput(这两者亦由 DataInputStream和DataOutputStream实现)接口之外,它们与那些分层结构并无什么关系。它甚至没实用到现有InputStream 或OutputStream 类的功能——採用的是一个全然不相干的类。

该类属于全新的设计,含有自己的全部(大多数为固有)方法。

之所以要这样做,是由于RandomAccessFile 拥有与其它 IO类型全然不同的行为。由于我们可在一个文件中向前或向后移动。无论在哪种情况下。它都是独立运作的,作为Object 的一个“直接继承人”使用。

从根本上说,RandomAccessFile 相似DataInputStream和 DataOutputStream的联合使用。

当中,getFilePointer()用于了解当前在文件的什么地方。seek()用于移至文件内的一个新地点。而 length()用于推断文件的最大长度。

此外,构建器要求使用还有一个自变量(与C 的fopen()全然一样)。指出自己仅仅是随机读("r")。还是读写兼施("rw")。这里没有提供对“仅仅写文件”的支持。也就是说,假如是从DataInputStream继承的,那么 RandomAccessFile也有可能能非常好地工作。

还有更难对付的。非常easy想象我们有时要在其它类型的数据流中搜索,比方一个ByteArrayInputStream。但搜索方法仅仅有RandomAccessFile 才会提供。而后者仅仅能针对文件才干操作,不能针对数据流操作。此时。BufferedInputStream 确实同意我们标记一个位置(使用mark(),它的值容纳于单个内部变量中)。并用reset()重设那个位置。但这些做法都存在限制。并非特别实用。

1.  File类

File 类有一个欺骗性的名字——一般会觉得它对付的是一个文件。但实情并非如此。它既代表一个特定文件的名字,也代表文件夹内一系列文件的名字。若代表一个文件集。便可用list()方法查询这个集,返回的是一个字串数组。之所以要返回一个数组,而非某个灵活的集合类。是由于元素的数量是固定的。并且若想得到

一个不同的文件夹列表。仅仅需创建一个不同的File 对象就可以。其实,“FilePath”(文件路径)似乎是一个更好的名字。

1.1             文件夹列表器

如果想观看一个文件夹列表。可用两种方式列出File 对象。若在不含自变量(參数)的情况下调用list(),会获得 File 对象包括的一个完整列表。

然而。若想对这个列表进行某些限制,就须要使用一个“文件夹过滤器”,该类的作用是指出应怎样选择File 对象来完毕显示。

样例的代码:

l  代码例如以下

import java.io.*;

public classDirList {

public static void main(String[] args) {

try {

Filepath= newFile(".");

String[]list;

if (args.length == 0)

list = path.list();

else

list = path.list(new DirFilter(args[0]));

for (int i = 0; i < list.length; i++)

System.out.println(list[i]);

}catch(Exception e) {

e.printStackTrace();

}

}

}

class DirFilter implements FilenameFilter {

Stringafn;

DirFilter(Stringafn){

this.afn = afn;

}

public boolean accept(File dir, String name) {

// Strip path information:

Stringf = new File(name).getName();

return f.indexOf(afn) != -1;

}

} /// :~

l  运行

.classpath

.project

.settings

bin

src

DirFilter 类“实现”了interface FilenameFilter。

以下让我们看看FilenameFilter接口有多么简单:

public interface FilenameFilter {

boolean accept(文件文件夹, 字串名);

}

它指出这样的类型的全部对象都提供了一个名为 accept()的方法。之所以要创建这样的一个类,背后的全部原因就是把accept()方法提供给 list()方法。使list()可以“回调”accept(),从而推断应将哪些文件名称包括到列表中。因此,通常将这样的技术称为“回调”,有时也称为“算子”(也就是说,DirFilter 是一个算子,由于它唯一的作用就是容纳一个方法)。

由于 list()採用一个 FilenameFilter 对象作为自己的自变量使用。所以我们能传递实现了FilenameFilter 的不论什么类的一个对象,用它决定(甚至在运行期)list()方法的行为方式。

回调的目的是在代码的行为上提供更大的灵活性。

通过DirFilter。我们看出虽然一个“接口”仅仅包括了一系列方法。但并不局限于仅仅能写那些方法(可是。至少必须提供一个接口内全部方法的定义。

在这样的情况下,DirFilter 构建器也会创建)。accept()方法必须接纳一个 File 对象,用它指示用于寻找一个特定文件的文件夹;并接纳一个String,当中包括了要寻找之文件的名字。可决定使用或忽略这两个參数之中的一个。但有时至少要使用文件名称。

记住list()方法准备为文件夹对象中的每一个文件名称调用accept(),核实哪个应包括在内——详细由 accept()返回的“布尔”结果决定。

为确定我们操作的仅仅是文件名称,当中没有包括路径信息,必须採用String对象,并在它的外部创建一个File 对象。

然后调用 getName()。它的作用是去除全部路径信息(採用与平台无关的方式)。随后,accept()用String 类的indexOf()方法检查文件名称内部是否存在搜索字串"afn"。

若在字串内找到 afn,那么返回值就是afn 的起点索引;但假如没有找到,返回值就是-1。

注意这仅仅是一个简单的字串搜索样例。未使用常见的表达式“通配符”方案,比方"fo?.b?r*";这样的方案更难实现。

list()方法返回的是一个数组。

可查询这个数组的长度,然后在当中遍历,选定数组元素。

与 C 和C++的相似行为相比,这样的于方法内外方便游历数组的行为无疑是一个显著的进步。

1.2             匿名内部类

l  代码例如以下

用一个匿名内部类来重写显得非常理想。首先创建了一个filter()方法,它返回指向FilenameFilter 的一个句柄:

import java.io.*;

public classDirList2 {

public static FilenameFilter filter(final String afn) {

// Creation of anonymous inner class:

return new FilenameFilter() {

Stringfn = afn;

public boolean accept(File dir, String n) {

// Strip path information:

Stringf = new File(n).getName();

return f.indexOf(fn) != -1;

}

};// End of anonymous inner class

}

public static void main(String[] args) {

try {

Filepath= newFile(".");

String[]list;

if (args.length == 0)

list = path.list();

else

list = path.list(filter(args[0]));

for (int i = 0; i < list.length; i++)

System.out.println(list[i]);

}catch(Exception e) {

e.printStackTrace();

}

}

} /// :~

l  运行

.classpath

.project

.settings

bin

src

注意filter()的自变量必须是final。

这一点是匿名内部类要求的,使其能使用来自本身作用域以外的一个对象。

之所以觉得这样做更好,是由于FilenameFilter 类如今同DirList2 紧密地结合在一起。然而,我们可採取进一步的操作,将匿名内部类定义成list()的一个參数,使其显得更加精简。

l  代码2

import java.io.*;

public classDirList3 {

public static void main(final String[] args) {

try {

Filepath= newFile(".");

String[]list;

if (args.length == 0)

list = path.list();

else

list = path.list(new FilenameFilter() {

public boolean accept(File dir, String n) {

Stringf = new File(n).getName();

return f.indexOf(args[0]) != -1;

}

});

for (int i = 0; i < list.length; i++)

System.out.println(list[i]);

}catch(Exception e) {

e.printStackTrace();

}

}

} /// :~

l  运行

.classpath

.project

.settings

bin

src

main()如今的自变量是 final。由于匿名内部类直接使用args[0]。

这展示了怎样利用匿名内部类高速创建精简的类。以便解决一些复杂的问题。由于Java 中的全部东西都与类有关,所以它无疑是一种相当实用的编码技术。它的一个优点是将特定的问题隔离在一个地方统一解决。但在还有一方面,这样生成的代码不是十分easy阅读,所以使用时必须谨慎。

1.3             顺序文件夹列表

常常都须要文件名称以排好序的方式提供。由于 Java 1.0 和Java 1.1 都没有提供对排序的支持(从 Java 1.2開始提供),用创建的 SortVector将这一能力直接添加自己的程序。

l  代码

import java.io.*;

public classSortedDirList {

private File path;

private String[] list;

public SortedDirList(final String afn) {

path = new File(".");

if (afn == null)

list = path.list();

else

list = path.list(new FilenameFilter() {

public boolean accept(File dir, String n) {

Stringf = new File(n).getName();

return f.indexOf(afn) != -1;

}

});

sort();

}

void print() {

for (int i = 0; i < list.length; i++)

System.out.println(list[i]);

}

private void sort() {

StrSortVectorsv = new StrSortVector();

for (int i = 0; i < list.length; i++)

sv.addElement(list[i]);

// The first time an element is pulled from

// the StrSortVector the list is sorted:

for (int i = 0; i < list.length; i++)

list[i] = sv.elementAt(i);

}

// Test it:

public static void main(String[] args) {

SortedDirListsd;

if (args.length == 0)

sd = new SortedDirList(null);

else

sd = new SortedDirList(args[0]);

sd.print();

}

} /// :~

l  运行

.classpath

.project

.settings

bin

src

这里进行了另外少许改进。不再是将path(路径)和 list(列表)创建为main()的本地变量,它们变成了类的成员。使它们的值能在对象“生存”期间方便地訪问。其实。main()如今仅仅是对类进行測试的一种方式。

一旦列表创建完毕,类的构建器就会自己主动開始对列表进行排序。

这样的排序不要求区分大写和小写,所以终于不会得到一组全部单词都以大写字母开头的列表。跟着是全部以小写字母开头的列表。

然而,我们注意到在以同样字母开头的一组文件名称中。大写字母是排在前面的——这对标准的排序来说仍是一种不合格的行为。

Java 1.2 已成功攻克了这个问题。

1.4             检查与创建文件夹

File 类并不仅仅是对现有文件夹路径、文件或者文件组的一个表示。亦可用一个 File 对象新建一个文件夹,甚至创建一个完整的文件夹路径——假如它尚不存在的话。

亦可用它了解文件的属性(长度、上一次改动日期、读/写属性等),检查一个File 对象究竟代表一个文件还是一个文件夹。以及删除一个文件等等。下列程序完整展示了怎样运用File 类剩下的这些方法:

l  代码

import java.io.*;

public classMakeDirectories {

private final static String usage = "Usage:MakeDirectories path1 ...\n" + "Creates each path\n"

+"Usage:MakeDirectories -d path1...\n" + "Deleteseach path\n" + "Usage:MakeDirectories -r path1 path2\n"

+"Renames from path1 to path2\n";

private static void usage() {

System.err.println(usage);

System.exit(1);

}

private static void fileData(File f) {

System.out.println("Absolute path: "+ f.getAbsolutePath()+ "\n Can read: " + f.canRead() + "\n Can write: "

+f.canWrite() + "\n getName: "+ f.getName() + "\n getParent: "+ f.getParent() + "\n getPath: "

+f.getPath() + "\n length: "+ f.length() + "\n lastModified: "+ f.lastModified());

if (f.isFile())

System.out.println("it's a file");

else if (f.isDirectory())

System.out.println("it's a directory");

}

public static void main(String[] args) {

if (args.length < 1)

usage();

if (args[0].equals("-r")) {

if (args.length != 3)

usage();

Fileold= newFile(args[1]),rname= newFile(args[2]);

old.renameTo(rname);

fileData(old);

fileData(rname);

return; // Exit main

}

int count = 0;

boolean del = false;

if (args[0].equals("-d")) {

count++;

del = true;

}

for (; count < args.length; count++) {

Filef = new File(args[count]);

if (f.exists()) {

System.out.println(f + " exists");

if (del) {

System.out.println("deleting..."+ f);

f.delete();

}

}else{ // Doesn't exist

if (!del) {

f.mkdirs();

System.out.println("created "+ f);

}

}

fileData(f);

}

}

} /// :~

l  运行

Usage:MakeDirectories path1 ...

Creates each path

Usage:MakeDirectories -d path1 ...

Deletes each path

Usage:MakeDirectories -r path1 path2

Renames from path1 to path2

加上运行參数:-rtest1.txt test2.txt

然后在文件夹中添加test1.txt文件,运行后

Absolute path: F:\java_test\test1.txt

Can read: false

Can write: false

getName: test1.txt

getParent: null

getPath: test1.txt

length: 0

lastModified: 0

Absolute path: F:\java_test\test2.txt

Can read: true

Can write: true

getName: test2.txt

getParent: null

getPath: test2.txt

length: 0

lastModified: 1460890496589

it's a file

在fileData()中。可看到应用了各种文件调查方法来显示与文件或文件夹路径有关的信息。

main()应用的第一个方法是 renameTo(),利用它可以重命名(或移动)一个文件至一个全新的路径(该路径由參数决定),它属于还有一个File 对象。这也适用于不论什么长度的文件夹。

若试验上述程序。就可发现自己能制作随意复杂程度的一个文件夹路径,由于mkdirs()会帮我们完毕全部工作。在Java 1.0 中,-d标志报告文件夹虽然已被删除,但它依旧存在。但在 Java 1.1 中,文件夹会被实际删除。

2.  附SortVector.java

import java.util.*;

public classSortVector extends Vector {

private Compare compare; // To hold the callback

public SortVector(Compare comp) {

compare = comp;

}

public void sort() {

quickSort(0,size() - 1);

}

private void quickSort(int left, int right) {

if (right > left) {

Objecto1 = elementAt(right);

int i = left - 1;

int j = right;

while (true) {

while (compare.lessThan(elementAt(++i), o1))

;

while (j > 0)

if (compare.lessThanOrEqual(elementAt(--j), o1))

break; // out of while

if (i >= j)

break;

swap(i, j);

}

swap(i, right);

quickSort(left, i - 1);

quickSort(i + 1, right);

}

}

private void swap(int loc1, int loc2) {

Objecttmp= elementAt(loc1);

setElementAt(elementAt(loc2), loc1);

setElementAt(tmp, loc2);

}

} /// :~

3.  附StrSortVector.java

import java.util.*;

interface Compare {

boolean lessThan(Object lhs, Object rhs);

boolean lessThanOrEqual(Object lhs, Object rhs);

} /// :~

public classStrSortVector{

private SortVector v = new SortVector(

// Anonymous inner class:

new Compare() {

public boolean lessThan(Object l, Object r) {

return ((String) l).toLowerCase().compareTo(((String)r).toLowerCase())< 0;

}

public boolean lessThanOrEqual(Object l, Object r) {

return ((String) l).toLowerCase().compareTo(((String)r).toLowerCase())<= 0;

}

});

private boolean sorted = false;

public void addElement(String s) {

v.addElement(s);

sorted = false;

}

public String elementAt(int index) {

if (!sorted) {

v.sort();

sorted = true;

}

return (String) v.elementAt(index);

}

public Enumerationelements() {

if (!sorted) {

v.sort();

sorted = true;

}

return v.elements();

}

// Test it:

public static void main(String[] args) {

StrSortVector sv = new StrSortVector();

sv.addElement("d");

sv.addElement("A");

sv.addElement("C");

sv.addElement("c");

sv.addElement("b");

sv.addElement("B");

sv.addElement("D");

sv.addElement("a");

Enumeratione = sv.elements();

while (e.hasMoreElements())

System.out.println(e.nextElement());

}

} /// :~

33.JAVA编程思想——JAVA IO File类相关推荐

  1. 35.JAVA编程思想——JAVA IO StreamTokenizer

    35.JAVA编程思想--JAVA IO StreamTokenizer 尽管StreamTokenizer并不是从 InputStream或 OutputStream衍生的,但它只随同InputSt ...

  2. 71.JAVA编程思想——JAVA与CGI

    71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST ...

  3. Java编程思想读书笔记——复用类

    第七章 复用类 组合和继承是复用类的两种主要方式. 7.1 组合语法 组合只需将对象引用置于新类中即可.这些引用的初始化方式有四种: 1) 在定义对象的地方进行初始化,即在创建新类对象前就被初始化: ...

  4. java:IO流(缓冲流、对象流、控制台IO、转换流、java.io.File 类 )

    目录 一.IO 流的结构体系 二.缓冲流:BufferedInputStream & BufferedOutputStream 三.对象流:ObjectInputStream & Ob ...

  5. 类的包访问权限:《Java编程思想》中一段话的困惑

    类的包访问权限:<Java编程思想>中一段话的困惑 在<java编程思想第三版>(陈昊鹏 饶若楠等译)的第五章隐藏具体实现中,5.4节的最后一段话是: "正如前面所提 ...

  6. 利用java.io.File类实现遍历本地磁盘上指定盘符或文件夹的所有的文件

    2016-11-18 这是本人的第一篇随笔博客,纠结了半天还是选择自己学的时候比较用心的一些知识点上.利用java.io.File类指定本地的文件夹进行遍历所有的文件. package org.lxm ...

  7. Java笔记整理六(File类,递归,字节流IO,字符流IO,流中的异常处理,属性集Properties,缓冲流,转换流,序列化,打印流)

    1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 文件和目录路径名的抽象表示 java把文件和文件夹封装位为一个File类,我们可 ...

  8. Java编程思想日志

    Thinking In Java的作者是大牛!做事要站在巨人的肩膀上有助于提高效率和开阔眼界!建议学习java的小伙伴儿有时间可以抽空了解一下,以下内容为读书笔记,比较杂乱,仅供参考,推荐阅读原著: ...

  9. Java编程思想第四版学习总结

    Java编程思想第四版学习总结 文章目录 Java编程思想第四版学习总结 第 1 章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重 ...

最新文章

  1. vsftp和nfs服务
  2. loadrunner关联点总结
  3. Spring Boot中配置文件application.properties使用
  4. 第一章 Linux系统简介
  5. linux入门_linux入门-常用命令的使用
  6. python中selenium中使用ajax_Selenium测试Ajax程序(转)
  7. linux下slow,慢查询日志的分析工具mysqlsla的使用
  8. Ping记录时间的方法
  9. 关于java的回调方法
  10. JSK-16014 打印字母图形【打印图案】
  11. 科研绘图神器之Plotluck(如何节省时间)
  12. 点击元素改变样式,再点击,又变回去,来回变
  13. ESP32-8位数码管
  14. 游戏公司用IM软件 “颜值”和“手感”一个都不能少
  15. 2022.6.14日新selenium写法
  16. pycharm所有版本 http://www.jetbrains.com/pycharm/download/previous.html 打开激活窗口 选择 Activate new license
  17. eclipse快捷键的设置和使用
  18. 有效缓解失眠的好物,睡前尝试这些助眠好物改善失眠
  19. Frustum culling
  20. 汇编语言的符号拓展指令CBW、CWD、CDQ、CWDE、CDQE

热门文章

  1. Jquery Highcharts 参数配置说明
  2. 对二进制文件的操作(c++ 程序设计 by 谭浩强 课本实例)
  3. HP DVD-ROM TS-L663M ATA Devices
  4. Ambari实现HTTPS登陆
  5. java里shake是什么意思_shake是什么意思_shake在线翻译_英语_读音_用法_例句_海词词典...
  6. python 精度损失_Python的浮点数损失精度问题
  7. android 滚动列表框,建立滚动列表框
  8. php返回支付状态,magento paypal返回支付状态
  9. it计算机哪些专业术语,IT之家学院:笔记本电脑专业术语科普
  10. vba 指定列后插入列_在不同的列左侧插入指定数量的空白列