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

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
class
DirList {

??? 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
class
DirList2 {

??? 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
class
DirList3 {

??? 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
class
SortedDirList {

??? 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
class
MakeDirectories {

??? 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
class
SortVector 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
class
StrSortVector{

??? 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());

??? }

} /// :~

?

?

原文地址:https://www.cnblogs.com/zhchoutai/p/8612025.html

时间: 2024-12-15 07:13:26

33.JAVA编程思想——JAVA IO File类的相关文章

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

71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST(上传).除此以外,Java 程序还可拦截CGI 程序的输出,所以不必依赖程序来格式化一个新页,也不必在出错的时候强迫用户从一个页回转到另一个页.事实上,程序的外观可以做得跟以前的版本别无二致. 代码也要简单一些,毕竟用CGI 也不是很难就能写出来(前提是真正地理解它).所以我们准备办个CGI 编程

81.JAVA编程思想——JAVA编程规则

81.JAVA编程思想--JAVA编程规则 (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsMethodOrFieldName 若在定义中出现了常数初始化字符,则大写static final 基本类型标识符中的所有字母.这样便可标志出它们属于编译期的常数. Java 包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此

java编程思想——java IO系统

一.什么是IO io在本质上是单个字节的移动.而流能够说是字节移动的载体和方式,它不停的向目标处移动数据.我们要做的就是依据流的方向从流中读取数据或者向流中写入数据. 二.java中支持IO操作的库类 1.依照数据类型分为两类: (1)字节类型:InputStream和OutputStream (2)字符类型:Writer和Reader 2.依照数据的流动方向,主要分为两类: (1)基于磁盘操作的io接口:File (2)基于网络的io接口:socket 三.字节流.字符流的io接口说明 字节流

Java编程思想学习(五) 复用类

1.继承与组合 复用类的方法有两种:继承与组合.继承就不多说了,组合就是直接在类中new一个对象. 数组也是对象,使用数组也是组合的一种. 2.初始化基类 当创建一个导出类的对象时,该对象包含一个基类的子对象.这个子对象跟直接new一个基类的对象完全相同,唯一的区别是:一个在外部,一个被包装在导出类对象内部. 在导出类构造器中,通过调用基类构造器来执行初始化.[在Java中,所有导出类的所有构造器内部都必须调用父类的某一个构造器或所有导出类的所有构造器内部都必须调用一个其他构造器(既可以是本类构

【Java编程思想】7.复用类

Java 中复用代码的方法: 组合:只需在新的类中产生现有类的对象. 继承:按照现有类的类型来创建新的类,无需改变现有类的形式. 代理:继承和组合之间的方式 7.1 组合语法 其实就是在一个类中引入其他类作为属性/域. 类中域为基本类型时会被自动初始化为0或 false,对象会被初始化为 null. 初始化对象的引用,可以在代码中的下列位置中进行: 在定义对象的地方-->意味着他们总是能够在构造器被调用前被初始化 在类的构造器中 在正要使用这些对象之前(惰性初始化/懒汉式/懒加载) 使用实例初始

java 编程思想-java运算符--以前不太明白的

1.java 运算符 主要是逻辑运算符和按位运算符;移位运算符-name tecmint.txt 逻辑运算符:And(&&) ; OR(||);Not(!) 按位运算符:And(&); OR(|); XOR(^);Not(~) 移位运算符:>> ; << ; >>> 按位运算符: public void test_and(){         int a = 128;     // 0000 0000 0000 0000 0000 0000

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

2016-11-18 这是本人的第一篇随笔博客,纠结了半天还是选择自己学的时候比较用心的一些知识点上.利用java.io.File类指定本地的文件夹进行遍历所有的文件. package org.lxm.filedemo; import java.io.File; import java.util.Scanner; /* * 本程序是将某个盘的所有文件夹及其文件全部调出来的操作 */ public class FileAllDemo { public static void main(String

Java编程思想(四) —— 复用类

看了老罗罗升阳的专访,情不自禁地佩服,很年轻,我之前以为和罗永浩一个级别的年龄,也是见过的不是初高中编程的一位大牛之一,专访之后,发现老罗也是一步一个脚印的人.别说什么难做,做不了,你根本就没去尝试,也没有去坚持. If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but whatever you do,you have to keep moving forward--Martin

《Java编程思想》学习01:普通类的初始化加载顺序分析

<Java编程思想>学习01:普通类的初始化加载顺序分析 本文根据控制变量法,分析普通类(没有extends,implement)初始化的加载顺序: 参考<Java编程思想>第五章 源码 StaticClass1类 package com.tyj.study.thinkinjava; /* * *@Description: *@Author:TYJ *@Date: create in 2019/7/9 17:22 */ public class StaticClass1 { { S