- 浏览: 1117400 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (349)
- javascript (28)
- objective-c&cocos2d (46)
- 开发备忘及常用java代码 (46)
- core java7学习笔记 (13)
- Mina (7)
- HTML5 (13)
- 系统集成项目管理工程师学习笔记 (10)
- 数据库系统原理学习笔记 (11)
- C++学习笔记 (10)
- C语言学习笔记 (5)
- 数据结构学习笔记 (4)
- 计算机网络原理学习笔记 (3)
- 计算机组成原理学习笔记 (2)
- 软件工程学习笔记 (6)
- 开发工具 (15)
- OSGI学习 (1)
- 学习笔记 (19)
- oracle (3)
- java tv (1)
- web server (5)
- javafx (1)
- 随笔 (8)
- 梦舞集 (4)
- 工作流 (3)
- 程序错误记录 (6)
- Windows (2)
- Linux (4)
- Git (1)
- 企业管理 (2)
- android (1)
- JVM (17)
- box2dweb (1)
- 操作系统学习笔记 (6)
- 英语学习 (1)
- Windows 8 应用商店 (1)
- Go语言 (1)
- docker (1)
- visualVM源码学习 (0)
- MariaDB (0)
- JAVA7 (2)
- 面向对象存储 (0)
- Hibernate (14)
- Spring (3)
- 项目构建 (0)
- 读源码学JAVA (0)
- mybatis (1)
- spring mvc (2)
- Javassist (0)
最新评论
-
白天看黑夜:
Apache Mina Server 2.0 中文参考手册(带 ...
Mina学习笔记二_基础 -
yjph83:
兄弟,你这个解决方案是什么什么啊?我现在遇到个问题跟你类似的! ...
Tomcat 8.0.11 移动端访问报400错误问题 -
comedsh:
你好,我也想为开源的做点事情,想让 tomcat-redis- ...
利用tomcat-redis-session-manager做session同步时自定义类对象属性保存不上的解决方法 -
bsr1983:
这个应该是浏览器内部设置的,你可以在Android上试一下别的 ...
javascript学习笔记八 -
787250527:
bsr1983 写道该值是浏览器内部的一个变量,只读的,不可修 ...
javascript学习笔记八
12.1 流
在Java程序设计语言中,一个可以读取字节序列的对象被称为输入流(input stream)。一个可以写入字节序列的对象被称为输出流(output stream)。在抽象类InputStream和OutputStream中对它们进行了说明。由于以字节为单位的流处理存储为Unicode码的信息很不方便,所以有一个专门的类层次来处理Unicode字符,这些类继承与抽象类Reader和Writer。它们的读写操作都是基于双字节的Unicode代码单元,而不是基于单字节。
不论是read方法还是write方法都能阻塞(block)一个线程直到自己被真正地读取或者写入。
这意味着如果流不能立即被读取或者写入(通常是因为网络连接繁忙),Java就会挂起这个调用的线程。这样就能够给其他线程提供机会去做有用的工作,同时这个方法将一直等待,直到流再次可用为止。
available方法能够检查目前可以读取的字节数。
12.2 完整的流结构
12.2.1 流过滤器的分层
FileInputStream和FileOutputStream能够把输入和输出流与磁盘文件关联起来。要想达到这一目的,只需要在构造器中给出文件名或者文件的具体路径名即可。
提示:因为所有在java.io中的类都是将相对路径名解释为起始于用户的当前工作目录,所以应该清楚当前的目录。可以通过调用System.getProperty("user.dir")来获得。
Java使用了一种很聪明的策略来划分这两种职责。一些流(例如FileInputStrean以及URL类中利用openStream方法来返回的输入流)可以从文件以及其他地方接收字节。另一些流(例如DataInputStram和PrintWiter)可以将字节组合成更加有用的数据类型。Java程序员采用将一个已经存在的流传递给另一个流的构造器方法,将这两种流结合起来,结合后的流被称为过滤流(filetered stream)。
总而言之,处理需要使用怪异的构造器对流进行分层之外,能够将流进行混合与匹配时Java非常实用的特性之一!
12.2.2 数据流
数据流支持读取所有Java基本类型的方法。
注意:依赖于所使用的平台,在内存中有两种方法存储整数和浮点数。假设正在使用4字节的整数,他的十进制数值为1234或者用十六进制表示为4D2,那么能够使用这种方式来存储。一种是内存中的四个字节的第一个字节用来存储最高有效字节(MSB),值为00 00 04 D2。这也被称为高字节前存法;另一种是从最低字节(LSB) 开始,值为D2 04 00 00。这种更加自然的方法称为低字节前存法。例如,SPARC使用的是高字节前存方法,奔腾使用的是低字节前存方法。这样一来就会出问题。当一个C或C++文件存储时,数据保持方式和处理器存储它们的方式一样,这样一来,即使把一个最简单的数据文件从一个平台移动到另一个平台都会遇到挑战。在Java中,不管在什么处理器上,所有的值都是采用高字节前存的方法存储的。这就使得Java的数据文件具有平台独立性。
注意:二进制数据格式是紧凑的并与平台无关。除了UTF字符串以外,其他的都可以随机存取,其主要的缺点是这些二进制文件不适合人们阅读。
12.2.3 随机存取文件流
RandomAccessFile流泪能够在文件的任何位置查找或者写入数据。它同时实现了DataInput和DataOutput接口。磁盘文件可以随机存取,但是来自网络的数据流就不行了。打开一个随机存取文件,要么进行制度操作,要么进行读写操作。可以通过构造器的第二个参数带入“r”(读取)或“rw”(读写)指定相应的操作。
当打开一个向右文件作为RandomAccessFile时,原来的文件不会被删除。
随进存取文件同时提供了一个文件指针(file pointer)。文件指针总是指向下一条要进行读取操作记录的位置。Seek方法将文件指针设定在文件内部的任意字节位置。Seek使用的参数是一个在0到文件长度(以字节计)之间的long整数。
12.2.4 文本流
Java提供了一套六过滤器作为Unicode字符码和本地操作系统使用的字符码间的桥梁。所有这些类都从抽象类Reader和Writer类派生出来,而名字会令人联想到用于二进制数据的名字。
12.2.5 字符集
字符集给出了双字节Unicode码序列与在本地字符编码中采用的字节序列间的映射。
字符集的名称不分大小写。
可以用官方名称或者任何一个别名调用静态方法forName来获得Charset:
Charset cset=Charset.forName("ISO-8859-1");
12.2.6 文本输出
进行文本输出时,应该使用PrintWriter。print writer可以以文本格式打印字符串和数值。与DataOutputStream类似,尽管提供了一些很有用的输出方法,但却没有定义目的地,一个PrintWriter必须与一个目标writer相结合。
12.2.7 文本输入
当以二进制格式写入数据时,应当使用DataOutputStream。
当以文本格式写入数据时,应当使用Printriter。
提示:Java的StringReader和StringWriter类可以像对待一个数据流一样对待字符串。这对于想要使用相同的代码从流中分析字符串和数据来说十分有用。
12.3 ZIP文件流
注意:处理ZIP文件的类在java.util.zip中而不在java.io中,所以请记住要添加必要的import语句。尽管不是java.io的一部分,但GZIP和ZIP类还是java.io.FilterInputStream和java.io.FilterOutPutStream的子类。java.util.zip包同样也包含了拥有计算循环冗余码校验(Cyclic Readundancy Check,CRC)的类。(CRC是用来生成类似散列码的方法,文件接收者可以使用这些来检验数据的完整性。)
12.4 流的使用
12.4.1 分隔符输出
12.4.2 字符串记号处理器和带分隔符的文本
java.util.StringTokenizer
12.4.3 读取带分隔符的输入
12.4.4 StringBuilder类
StringBuilder的工作过程更像一个ArrayList。它管理着一个可以根据需求增长或缩短的字符数组char[]。可以追加、插入或者删除代码单元,直到StringBuilder中含有的所希望的字符为止,然后使用toString方法将内同转换为一个真正的String对象。
注意:StringBuilder类是JDK5.0新引入的。它的前身StringBuffrt的效率稍稍低一点,但是却可以允许多线程进行增加或移除字符操作。如果所有的字符串编辑出现在一个线程中,应该使用StringBuilder。这两个类的API都是相同的。
12.4.5 随机存取流
12.5 对象流
12.5.1 存储可变类型的对象
12.5.2 理解对象序列化文件格式
对象序列化使用的是一种特殊的文件格式来存储对象。
Java从以下途径获得指纹:
首先用标准的方式对类、超类、接口、域类型和方法签名的描述进行排序。
然后对那些数据应用一种所谓的“安全散列算法”(Secure Hash Algorithm,SHA)
SHA是一种可以从大块的信息块中获取“指纹”的快速算法。不管原始数据多大,这种方法产生的指纹必然是一个长度为20字节的数据包。
注意:从技术上说,只要类的数据布局没有改变,都回一个对象就是安全的。但是,Java相对的保守,所以还会检查方法是不是被改变。(毕竟,方法描述了所保存的数据的意义。)当然,实际上,类是不断衍化的,所以成像读取对象的老版本也是必要的。
12.5 保存对象引用问题的解决
Java使用序列化(serialization)方法。这就是所谓的对象序列化(object serialization)机制。下面是具体的算法:
所有保存到磁盘的对象都有一个序列号。
当向磁盘存储一个对象时,先检查相同的对象是否已经保存。
如果已经存储过,只要写入“与已经存储的对象具有序列号X”。如果没有,保存所有的数据。
12.5.4 理解对象引用的输出格式
所有的对象(包括数组和字符串)以及类描述符在保持到输出文件时,都会获得一个序列号。因为每个保存的对象都会分配到一个唯一的序列号(从00 7E 00 00开始),这个处理流程被称为序列化(serralization).
通常,不必知道准确的文件格式(除非想尝试通过改变数据创造一个遗憾的效果。)应该记住下面这些:
对象流的输出包含所有对象的类型和数据域。
每个对象都会分配一个序列号。
重复出现的同一个对象会存储为其序列号的引用。
12.5.5 修改默认的序列化机制
Java有一个简单的机制用来避免这些域被序列化,即使用关键字transient标注他们。另外,还需要将那些属于非序列化中的域标注为transient。当对象被序列化时,标注为transient的域是会被跳过的。
提示:序列化有些慢,因为虚拟机必须弄清每个对象的结构,如果关心性能,并且需要读写大量的特定类对象,就应该考虑使用Externalizable接口。
警告:不同于readObject和writeObject方法,他们是私有的并且只能被序列化机制调用,readExternal和writeExternal方法是公有的。特别是,readExternal方法潜在地运行对一个已经存在的对象状态进行修改。
12.5.6 单元素与类型安全枚举的序列化
12.5.7 版本
类可以指出自己兼容于其早期版本。为了实现这一点,首先必须获得该类的早期版本的指纹,可以使用一个独立的程序serialver,它是JDK的一部分来获得这个数值。
12.5.8 使用序列化进行克隆
序列化机制提供了一种很简单的方法来克隆一个对象,只要被提供的类是序列化的。
要克隆一个序列化的对象,只需要就爱你过对象序列化到输出流中,然后读回即可。其结果是一个新的对已存在对象进行了深度拷贝的对象。不需要将对象写入文件——可以使用一个ByteArrayOutputStream来存储数据到一个字节数组中。
12.6 文件管理
注意:就像Java中经常使用的方法那样,File类也仅仅有最少的公共操作方法。比如在Windows中,可以查询(或设置)文件的只读标志,但尽管可以查询一个文件是否隐藏,却不能将它设置为隐藏,除非使用本地方法。
提示:如果处理文件或者目录名,就应该使用File对象,而不是字符串。
警告:如果在Windows中构造File对象时,使用正斜杠作为目录分隔符,那么getAbsolutePath方法将但会一个包括正斜杠的文件名,Windows用户会感觉有点奇怪。实际上,应该使用geCanonicalPath方法。它将使用反斜杠代替正斜杠。
12.7 新的I/O
JDK4.0包含了一些改进输入、输出处理的新特性,它们包含在java.nio包中,被称为“新的I/O”。
此包支持下列特性:
内存映射文件
文件锁定
字符集编码和解码
非阻塞I/O
12.7.1
使用java.nio包建立内存映射很简单。下面是需要的步骤:
首先,为文件获取通道(channel)。通道时对于磁盘文件的抽象,允许访问操作系统的特性,如文件间的内存映射、文件锁定和快速数据传输。通过调用增加到FileInputStream、FileOutputStream和RandomAccessFile类中的getChannel方法就可以获得通道。
FileInputStream in=new FileInputStream(...);
FileChannel channel=in.getChannel();
通过调用FileChannel类的map方法可以获得MappedByteBuffer。可以指定需要进行映射的文件区域和映射模式。有三种模式:
FileChannel.MapMode.READ_ONLY:结果缓存区是只读的。任何试图写入缓存区的举动都将抛出ReadOnlyBufferException。
FileChannel.MapMode.READ_WRITE:结果缓存区可写,这些改变会及时写会文件中。注意,如果其他程序也映射了同一个文件,它并不会立即观察到这些变化。多个程序同时对同一文件进行映射的具体行为依赖于操作系统。
FileChannel.MapMode.PRIVATE:结果缓存区可写,但是任何改变都是私有的,仅仅对该缓存区有效,并不会写入文件中。
一旦获取了缓冲区,可以用ByteBuffer类和Buffer超类读写数据。
缓冲区支持顺序和随机数据访问。缓冲区有一个被get和put操作使用的位置。
12.7.2 缓存区数据结构
当使用内存映射时,制作了一个横跨整个文件的缓冲区,或者是文件中的一个感兴趣的区域。也可以使用缓冲区来读写更多的普通信息块。
一个缓冲区就是一个相同类型的值的数组。Buffer类是一个抽象类,它包含以下子类:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer。在实际应用中,使用最多的是ByteBuffer和CharBuffer。
一个缓存区具有:
一个绝不会改变的容量(capacity)。
一个下一数值读取或写入的位置(position)。
一个限制(limit),超出这个限制的读写时无意义的。
可选地,一个重复进行读写操作的标志(mark)。
12.7.3 文件锁定
要锁住一个文件,调用FileChannel类的lock或tryLock方法:
File lock=channel.lock();
或者
File lock=channel.tryLock();
第一个调用一直处于阻塞状态直到该锁可用。第二个调用立刻返回,返回该锁或者是null(如果该锁不可用)。第一个文件保持封锁状态知道通道关闭,或者对锁调用release方法。
注意:如果锁住文件的尾部,而文件后来增加的内容超过了锁住的位置,则多出的部分并没有锁住。要锁住全部字节,使用大小为Long.MAX_VALUE。
记住文件锁是与系统相关的。要注意以下几点:
在一些系统中,文件锁仅仅是建议性的(advisory)。因此,如果一个应用程序未能获得锁,它也可以对文件进行读写操作,尽管其他应用程序已经锁住文件。
在一些系统中,不能同步地锁住一个文件并把它映射到内存中。
文件锁是整个Java虚拟机持有的。如果两个程序使用同一个虚拟机执行(例如,一个applet或者应用程序启动器),则它们不能对同一个文件获得锁。如果虚拟机已经拥有了对同一个文件的重叠锁,则lock或者truLock方法会抛出OverlappingFileLockException异常。
在某些系统上,关闭通道会释放Java虚拟机拥有的文件上全部的锁。因此应该避免对同一个被锁定的文件打开多个通道。
对网络文件系统中的文件锁定是和系统高度相关的,因此应该避免这么做。
12.8 正则表达式
正则表达式是用来指定字符串模式的。任何时候只要需要定位一个匹配特定模式的字符串,都可以使用正则表达式。
在Java程序设计语言中,一个可以读取字节序列的对象被称为输入流(input stream)。一个可以写入字节序列的对象被称为输出流(output stream)。在抽象类InputStream和OutputStream中对它们进行了说明。由于以字节为单位的流处理存储为Unicode码的信息很不方便,所以有一个专门的类层次来处理Unicode字符,这些类继承与抽象类Reader和Writer。它们的读写操作都是基于双字节的Unicode代码单元,而不是基于单字节。
不论是read方法还是write方法都能阻塞(block)一个线程直到自己被真正地读取或者写入。
这意味着如果流不能立即被读取或者写入(通常是因为网络连接繁忙),Java就会挂起这个调用的线程。这样就能够给其他线程提供机会去做有用的工作,同时这个方法将一直等待,直到流再次可用为止。
available方法能够检查目前可以读取的字节数。
12.2 完整的流结构
12.2.1 流过滤器的分层
FileInputStream和FileOutputStream能够把输入和输出流与磁盘文件关联起来。要想达到这一目的,只需要在构造器中给出文件名或者文件的具体路径名即可。
提示:因为所有在java.io中的类都是将相对路径名解释为起始于用户的当前工作目录,所以应该清楚当前的目录。可以通过调用System.getProperty("user.dir")来获得。
Java使用了一种很聪明的策略来划分这两种职责。一些流(例如FileInputStrean以及URL类中利用openStream方法来返回的输入流)可以从文件以及其他地方接收字节。另一些流(例如DataInputStram和PrintWiter)可以将字节组合成更加有用的数据类型。Java程序员采用将一个已经存在的流传递给另一个流的构造器方法,将这两种流结合起来,结合后的流被称为过滤流(filetered stream)。
总而言之,处理需要使用怪异的构造器对流进行分层之外,能够将流进行混合与匹配时Java非常实用的特性之一!
12.2.2 数据流
数据流支持读取所有Java基本类型的方法。
注意:依赖于所使用的平台,在内存中有两种方法存储整数和浮点数。假设正在使用4字节的整数,他的十进制数值为1234或者用十六进制表示为4D2,那么能够使用这种方式来存储。一种是内存中的四个字节的第一个字节用来存储最高有效字节(MSB),值为00 00 04 D2。这也被称为高字节前存法;另一种是从最低字节(LSB) 开始,值为D2 04 00 00。这种更加自然的方法称为低字节前存法。例如,SPARC使用的是高字节前存方法,奔腾使用的是低字节前存方法。这样一来就会出问题。当一个C或C++文件存储时,数据保持方式和处理器存储它们的方式一样,这样一来,即使把一个最简单的数据文件从一个平台移动到另一个平台都会遇到挑战。在Java中,不管在什么处理器上,所有的值都是采用高字节前存的方法存储的。这就使得Java的数据文件具有平台独立性。
注意:二进制数据格式是紧凑的并与平台无关。除了UTF字符串以外,其他的都可以随机存取,其主要的缺点是这些二进制文件不适合人们阅读。
12.2.3 随机存取文件流
RandomAccessFile流泪能够在文件的任何位置查找或者写入数据。它同时实现了DataInput和DataOutput接口。磁盘文件可以随机存取,但是来自网络的数据流就不行了。打开一个随机存取文件,要么进行制度操作,要么进行读写操作。可以通过构造器的第二个参数带入“r”(读取)或“rw”(读写)指定相应的操作。
当打开一个向右文件作为RandomAccessFile时,原来的文件不会被删除。
随进存取文件同时提供了一个文件指针(file pointer)。文件指针总是指向下一条要进行读取操作记录的位置。Seek方法将文件指针设定在文件内部的任意字节位置。Seek使用的参数是一个在0到文件长度(以字节计)之间的long整数。
12.2.4 文本流
Java提供了一套六过滤器作为Unicode字符码和本地操作系统使用的字符码间的桥梁。所有这些类都从抽象类Reader和Writer类派生出来,而名字会令人联想到用于二进制数据的名字。
12.2.5 字符集
字符集给出了双字节Unicode码序列与在本地字符编码中采用的字节序列间的映射。
字符集的名称不分大小写。
可以用官方名称或者任何一个别名调用静态方法forName来获得Charset:
Charset cset=Charset.forName("ISO-8859-1");
12.2.6 文本输出
进行文本输出时,应该使用PrintWriter。print writer可以以文本格式打印字符串和数值。与DataOutputStream类似,尽管提供了一些很有用的输出方法,但却没有定义目的地,一个PrintWriter必须与一个目标writer相结合。
12.2.7 文本输入
当以二进制格式写入数据时,应当使用DataOutputStream。
当以文本格式写入数据时,应当使用Printriter。
提示:Java的StringReader和StringWriter类可以像对待一个数据流一样对待字符串。这对于想要使用相同的代码从流中分析字符串和数据来说十分有用。
12.3 ZIP文件流
注意:处理ZIP文件的类在java.util.zip中而不在java.io中,所以请记住要添加必要的import语句。尽管不是java.io的一部分,但GZIP和ZIP类还是java.io.FilterInputStream和java.io.FilterOutPutStream的子类。java.util.zip包同样也包含了拥有计算循环冗余码校验(Cyclic Readundancy Check,CRC)的类。(CRC是用来生成类似散列码的方法,文件接收者可以使用这些来检验数据的完整性。)
12.4 流的使用
12.4.1 分隔符输出
12.4.2 字符串记号处理器和带分隔符的文本
java.util.StringTokenizer
12.4.3 读取带分隔符的输入
12.4.4 StringBuilder类
StringBuilder的工作过程更像一个ArrayList。它管理着一个可以根据需求增长或缩短的字符数组char[]。可以追加、插入或者删除代码单元,直到StringBuilder中含有的所希望的字符为止,然后使用toString方法将内同转换为一个真正的String对象。
注意:StringBuilder类是JDK5.0新引入的。它的前身StringBuffrt的效率稍稍低一点,但是却可以允许多线程进行增加或移除字符操作。如果所有的字符串编辑出现在一个线程中,应该使用StringBuilder。这两个类的API都是相同的。
12.4.5 随机存取流
12.5 对象流
12.5.1 存储可变类型的对象
12.5.2 理解对象序列化文件格式
对象序列化使用的是一种特殊的文件格式来存储对象。
Java从以下途径获得指纹:
首先用标准的方式对类、超类、接口、域类型和方法签名的描述进行排序。
然后对那些数据应用一种所谓的“安全散列算法”(Secure Hash Algorithm,SHA)
SHA是一种可以从大块的信息块中获取“指纹”的快速算法。不管原始数据多大,这种方法产生的指纹必然是一个长度为20字节的数据包。
注意:从技术上说,只要类的数据布局没有改变,都回一个对象就是安全的。但是,Java相对的保守,所以还会检查方法是不是被改变。(毕竟,方法描述了所保存的数据的意义。)当然,实际上,类是不断衍化的,所以成像读取对象的老版本也是必要的。
12.5 保存对象引用问题的解决
Java使用序列化(serialization)方法。这就是所谓的对象序列化(object serialization)机制。下面是具体的算法:
所有保存到磁盘的对象都有一个序列号。
当向磁盘存储一个对象时,先检查相同的对象是否已经保存。
如果已经存储过,只要写入“与已经存储的对象具有序列号X”。如果没有,保存所有的数据。
12.5.4 理解对象引用的输出格式
所有的对象(包括数组和字符串)以及类描述符在保持到输出文件时,都会获得一个序列号。因为每个保存的对象都会分配到一个唯一的序列号(从00 7E 00 00开始),这个处理流程被称为序列化(serralization).
通常,不必知道准确的文件格式(除非想尝试通过改变数据创造一个遗憾的效果。)应该记住下面这些:
对象流的输出包含所有对象的类型和数据域。
每个对象都会分配一个序列号。
重复出现的同一个对象会存储为其序列号的引用。
12.5.5 修改默认的序列化机制
Java有一个简单的机制用来避免这些域被序列化,即使用关键字transient标注他们。另外,还需要将那些属于非序列化中的域标注为transient。当对象被序列化时,标注为transient的域是会被跳过的。
提示:序列化有些慢,因为虚拟机必须弄清每个对象的结构,如果关心性能,并且需要读写大量的特定类对象,就应该考虑使用Externalizable接口。
警告:不同于readObject和writeObject方法,他们是私有的并且只能被序列化机制调用,readExternal和writeExternal方法是公有的。特别是,readExternal方法潜在地运行对一个已经存在的对象状态进行修改。
12.5.6 单元素与类型安全枚举的序列化
12.5.7 版本
类可以指出自己兼容于其早期版本。为了实现这一点,首先必须获得该类的早期版本的指纹,可以使用一个独立的程序serialver,它是JDK的一部分来获得这个数值。
12.5.8 使用序列化进行克隆
序列化机制提供了一种很简单的方法来克隆一个对象,只要被提供的类是序列化的。
要克隆一个序列化的对象,只需要就爱你过对象序列化到输出流中,然后读回即可。其结果是一个新的对已存在对象进行了深度拷贝的对象。不需要将对象写入文件——可以使用一个ByteArrayOutputStream来存储数据到一个字节数组中。
12.6 文件管理
注意:就像Java中经常使用的方法那样,File类也仅仅有最少的公共操作方法。比如在Windows中,可以查询(或设置)文件的只读标志,但尽管可以查询一个文件是否隐藏,却不能将它设置为隐藏,除非使用本地方法。
提示:如果处理文件或者目录名,就应该使用File对象,而不是字符串。
警告:如果在Windows中构造File对象时,使用正斜杠作为目录分隔符,那么getAbsolutePath方法将但会一个包括正斜杠的文件名,Windows用户会感觉有点奇怪。实际上,应该使用geCanonicalPath方法。它将使用反斜杠代替正斜杠。
12.7 新的I/O
JDK4.0包含了一些改进输入、输出处理的新特性,它们包含在java.nio包中,被称为“新的I/O”。
此包支持下列特性:
内存映射文件
文件锁定
字符集编码和解码
非阻塞I/O
12.7.1
使用java.nio包建立内存映射很简单。下面是需要的步骤:
首先,为文件获取通道(channel)。通道时对于磁盘文件的抽象,允许访问操作系统的特性,如文件间的内存映射、文件锁定和快速数据传输。通过调用增加到FileInputStream、FileOutputStream和RandomAccessFile类中的getChannel方法就可以获得通道。
FileInputStream in=new FileInputStream(...);
FileChannel channel=in.getChannel();
通过调用FileChannel类的map方法可以获得MappedByteBuffer。可以指定需要进行映射的文件区域和映射模式。有三种模式:
FileChannel.MapMode.READ_ONLY:结果缓存区是只读的。任何试图写入缓存区的举动都将抛出ReadOnlyBufferException。
FileChannel.MapMode.READ_WRITE:结果缓存区可写,这些改变会及时写会文件中。注意,如果其他程序也映射了同一个文件,它并不会立即观察到这些变化。多个程序同时对同一文件进行映射的具体行为依赖于操作系统。
FileChannel.MapMode.PRIVATE:结果缓存区可写,但是任何改变都是私有的,仅仅对该缓存区有效,并不会写入文件中。
一旦获取了缓冲区,可以用ByteBuffer类和Buffer超类读写数据。
缓冲区支持顺序和随机数据访问。缓冲区有一个被get和put操作使用的位置。
12.7.2 缓存区数据结构
当使用内存映射时,制作了一个横跨整个文件的缓冲区,或者是文件中的一个感兴趣的区域。也可以使用缓冲区来读写更多的普通信息块。
一个缓冲区就是一个相同类型的值的数组。Buffer类是一个抽象类,它包含以下子类:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer。在实际应用中,使用最多的是ByteBuffer和CharBuffer。
一个缓存区具有:
一个绝不会改变的容量(capacity)。
一个下一数值读取或写入的位置(position)。
一个限制(limit),超出这个限制的读写时无意义的。
可选地,一个重复进行读写操作的标志(mark)。
12.7.3 文件锁定
要锁住一个文件,调用FileChannel类的lock或tryLock方法:
File lock=channel.lock();
或者
File lock=channel.tryLock();
第一个调用一直处于阻塞状态直到该锁可用。第二个调用立刻返回,返回该锁或者是null(如果该锁不可用)。第一个文件保持封锁状态知道通道关闭,或者对锁调用release方法。
注意:如果锁住文件的尾部,而文件后来增加的内容超过了锁住的位置,则多出的部分并没有锁住。要锁住全部字节,使用大小为Long.MAX_VALUE。
记住文件锁是与系统相关的。要注意以下几点:
在一些系统中,文件锁仅仅是建议性的(advisory)。因此,如果一个应用程序未能获得锁,它也可以对文件进行读写操作,尽管其他应用程序已经锁住文件。
在一些系统中,不能同步地锁住一个文件并把它映射到内存中。
文件锁是整个Java虚拟机持有的。如果两个程序使用同一个虚拟机执行(例如,一个applet或者应用程序启动器),则它们不能对同一个文件获得锁。如果虚拟机已经拥有了对同一个文件的重叠锁,则lock或者truLock方法会抛出OverlappingFileLockException异常。
在某些系统上,关闭通道会释放Java虚拟机拥有的文件上全部的锁。因此应该避免对同一个被锁定的文件打开多个通道。
对网络文件系统中的文件锁定是和系统高度相关的,因此应该避免这么做。
12.8 正则表达式
正则表达式是用来指定字符串模式的。任何时候只要需要定位一个匹配特定模式的字符串,都可以使用正则表达式。
发表评论
-
第十三章 泛型程序设计
2010-10-25 17:22 142613.1 为什么要使用泛型 ... -
第十一章 异常与调试
2010-10-15 13:36 185811.1 处理错误 异常处理 ... -
第十章 部署applet和应用程序
2010-10-15 13:35 393910.1 applet基础 10.1.1 一个 ... -
第九章 Swing用户界面组件
2010-10-15 13:34 26249.1 模型-视图-控制器设计模式 注意:在设计模式中,模型存 ... -
第八章 事件处理
2010-10-11 20:00 17188.1 事件处理基础 事件源有一些向其注册事件监听器的方法。当 ... -
第七章 图形程序设计
2010-10-11 19:59 1555在JDK1.0刚刚出现的时候,包含了一个用于基本GUI程序设计 ... -
第六章 接口与内部类
2010-10-11 19:59 1262首先,介绍一下接口(i ... -
第五章 继承
2010-10-11 19:58 1291反射(reflection)是指在程序运行期间发现更多的类及其 ... -
第四章 对象与类
2010-10-11 19:57 12204.1 面向对象程序设计概述 4.1.1 OOP词汇表 类是构 ... -
第三章 Java基本的程序设计结构
2010-10-11 19:53 14233.1 一个简单的Java应用 ... -
第二章 Java程序设计环境
2010-10-11 19:52 12762.1 安装Java开发工具箱 2.1.1下载JDK 2.1. ... -
第一章 Java程序设计概述
2010-10-11 19:49 11121.1 Java程序设计平台 1.2 Java“白皮书”的关键 ...
相关推荐
根据提供的信息,我们可以总结出以下关于《Java语言程序设计基础第十版》第十二章的一些关键知识点及解答: ### 一、异常处理基本概念 #### 12.1 **问题:** 异常处理的主要思想是什么? **解答:** 异常处理的主要...
在Java编程中,输入输出流(Input/Output Stream)是数据传输的核心机制,用于处理程序与外部世界的交互,包括键盘、显示器、文件和网络等。本章主要关注的是输入输出流、文件操作以及数据库操作。 12.1 输入输出流...
由于您提供的文件信息仅包括标题、描述和部分内容,没有具体到第12章的习题答案,所以无法提供针对具体习题的详细解析。但是,我可以根据《C++ Primer》第五版的内容结构以及一般C++的学习顺序,为读者提供第12章...
本章主要探讨的是如何利用VBA进行文件的操作,包括打开、保存、读取和写入等基本功能,以及更高级的文件处理技巧。 1. **打开文件**: 使用`Workbooks.Open`函数可以打开一个Excel文件。例如,`Workbooks.Open ...
第12章 JDK8中的日期.pptx 第12章 字符串、日期.pptx 第13章 容器和泛型.pptx 第14章 流与文件(1).pptx 第14章 流与文件(2).pptx 第15章 网络编程.pptx 第1章 Java概述.pptx 第2章 Java基础.pptx 第3章 数组....
《12 教师用书_第12章_文件 2017021》章节主要讨论了C语言中的文件操作,包括文件的基本概念、类型、缓冲系统、文件结构、指针以及相关的操作函数。以下是详细的知识点解析: 1. **文件的基本概念**: 文件是数据...
本章主要讲解了如何在C语言中进行文件读写操作,涉及了以下几个关键知识点: 1. **什么是文件**:文件是保存在外存储器上的一组数据的有序集合,其特点是数据能够长久保存,长度可变,并且按照顺序存取。文件是程序...
第十二章 TR用法 第三部分 登录环境 第十三章 登录环境 第十四章 环境和SHELL变量 第十五章 小结 第四部分 基础SHELL编程 第十六章 SHELL脚本介绍 第十七章 条件测试 第十八章 控制流结构 第十九章 SHELL函数 第二...
在本章"C#2005文件IO与数据存取秘诀-第十二章"中,我们将深入探讨C#编程中的文件输入/输出(IO)操作和数据存储技术,特别是使用ADO.NET进行数据库交互。文件IO是任何软件开发中的基本部分,而数据存取则涉及到如何...
- **ASCII码文件**(文本文件):字符流文件,每个字符占用1字节,存放的是ASCII码,优点是可以直接阅读且易于移植,缺点是效率较低。 - **二进制文件**:按照内存中的存储形式存放数据,无需转换,效率高,但不可...
《JSP程序开发范例宝典》第十二章聚焦于JSP(Java Server Pages)的高级应用和实战技巧。在这一章中,我们通常会深入探讨以下关键知识点: 1. **自定义标签库(Custom Tags)**:JSP 2.0引入了自定义标签库的概念,...
本章主要讨论的是如何按字符进行读写文件。以下是一些关键知识点: 1. **标准输入输出流**: - `stdin`:标准输入流,通常关联到键盘,用于从用户那里获取输入。 - `stdout`:标准输出流,一般指向显示器,用于...
第十三章 文件 对数据的管理无论是用数组还是链表,都是存储在内存中的,程序结束后都会丢失,下一次运行程序时,要重新输入或运算生成数据。要把程序运行的数据保存起来以便下次运行继续使用,在计算机中持久保存...
6. **文件流**:FileInputStream和FileOutputStream是最常见的文件读写流,它们直接与文件系统交互。FileReader和FileWriter则用于处理文本文件。 7. **字符编码**:Java的I/O流系统支持多种字符编码,如ASCII、UTF...
《Java开发实战经典》是许多Java初学者的重要学习资料,其第十二章涵盖了诸多关键知识点。这章可能涉及了面向对象编程的深入理解、异常处理、集合框架的使用、多线程、网络编程或者IO流等内容。课后习题通常用于巩固...
字节流处理的是8位的字节数据,适合于处理任何类型的二进制数据,如图片、音频文件等。Java中的字节流主要有两个基类:`InputStream`(输入)和`OutputStream`(输出)。它们提供了一系列基本的读写操作,如`read()`...
在本章"C#2005文件IO与数据存取秘诀-第十一章"中,我们将深入探讨C#编程语言中关于文件输入/输出(I/O)和数据存取的关键概念和技术。C# 2005作为一个强大的开发平台,为开发者提供了丰富的API来处理文件操作和数据...
在北大青鸟S1JAVA课程的第十二章中,学员们会接触到一系列深入的Java编程概念和实践。这一章节的课后练习旨在巩固所学知识,提升编程技能。以下是本章涉及的一些关键知识点: 1. **面向对象编程基础**:在Java中,...