Java I/O系统##
18.1File类
- 目录列表器
File path = new File(".");
list = path.list(); //查看全部目录
list = path.list(new DirFilter(args[0]));//查看受限列表
class DirFilter implements FilenameFilter{
private Pattern pattern;
public DirFilter(String regex) {
pattern = Pattern.compile(regex);
}
@Override
public boolean accept(File dir, String name) {
return pattern.matcher(name).matches();
}
}
策略设计模式:一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
匿名内部类:
参数必须是final 的。
class DirFilter2 {
public static FilenameFilter filter(final String regex) {
return new FilenameFilter(){
Pattern pattern = Pattern.compile(regex);
@Override
public boolean accept(File dir, String name) {
return pattern.matcher(name).matches();
};
};
}
}
简写方式:
list = path.list( new FilenameFilter(){
Pattern pattern = Pattern.compile(args[0]);
@Override
public boolean accept(File dir, String name) {
return pattern.matcher(name).matches();
}
});
- 目录实用工具类
- 目录的检查及创建
18.2 输入和输出
-
InputStream类型
InputStream表示那些冲不同数据源产生输入的类。这些数据域包括:
字节数组,String对象,文件,管道,一个由其他种类的流组成的序列,其他数据源(internet连接等).
-
OutputStream类型
该类别的类决定了要去往的目标:字节数组,文件或管道。
18.3 添加属性或有用的接口
- 通过FilterInputStream从InputStream读取数据
- 通过FilterOutputStream从OutputStream读取数据
18.4 Reader和Writer
Reader和Writer主要是为了支持Unicode。
- 数据的来源和去处
18.6 I/O典型使用方式
- 缓冲输入文件
/**
* 缓冲输入文件
* @author Administrator
*
*/
public class BufferedInputFile {
public static String read(String filename) throws IOException {
BufferedReader in =
new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while ((s = in.readLine()) != null) {
sb.append(s+"\n");
}
in.close();
return sb.toString();
}
public static void main(String[] args) throws IOException {
String read = read("D:/javadata/workspace/ThinkInJava/src/com/thinkinjava/c18/DirList.java");
System.out.println(read);
}
}
- 从内存读入
/**
* 从内存读入
* @author Administrator
*
*/
public class MemoryInput {
public static void main(String[] args) throws IOException {
String filename = "D:/javadata/workspace/ThinkInJava/src/com/thinkinjava/c18/DirList.java";
StringReader in = new StringReader(BufferedInputFile.read(filename));
int c;
while ((c = in.read()) != -1) {
System.out.print((char)c);
}
}
}
- 格式化的内存读入
/**
* 格式化的内存读入
* @author Administrator
*
*/
public class FormitMemoryInput {
public static void main(String[] args) {
String filename = "D:/javadata/workspace/ThinkInJava/src/com/thinkinjava/c18/DirList.java";
try {
DataInputStream in = new DataInputStream(new ByteArrayInputStream( BufferedInputFile.read(filename).getBytes()));
while (in.available() != 0) {
System.out.print((char)in.readByte());
}
} catch (IOException e) {
}
}
}
- 基本的文件输出
/**
* 基本的文件输出
* @author Administrator
*
*/
public class BasicFileOutput {
static String file = "BasicFileOutput.out";
public static void main(String[] args) throws IOException {
String filename = "D:/javadata/workspace/ThinkInJava/src/com/thinkinjava/c18/DirList.java";
BufferedReader in =
new BufferedReader(new StringReader(
BufferedInputFile.read(filename)));
PrintWriter out =
new PrintWriter(new BufferedWriter(new FileWriter(file)));
int linecount = 0;
String s;
while ((s = in.readLine()) != null) {
out.println(linecount++ +":" +s);
}
out.close();
System.out.println(BufferedInputFile.read(filename));
}
}
- 存储和恢复数据
public class StoringAndRecoveringData {
public static void main(String[] args)
throws IOException {
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("Data.txt")));
out.writeDouble(3.14159);
out.writeUTF("That was pi");
out.writeDouble(1.41413);
out.writeUTF("Square root of 2");
out.close();
DataInputStream in = new DataInputStream(
new BufferedInputStream(
new FileInputStream("Data.txt")));
System.out.println(in.readDouble());
// Only readUTF() will recover the
// Java-UTF String properly:
System.out.println(in.readUTF());
System.out.println(in.readDouble());
System.out.println(in.readUTF());
}
}
- 读写随机访问文件
/**
* 读写随机访问文件
* @author Administrator
*
*/
public class UsingRandomAccessFile {
static String file = "rtest.dat";
static void display() throws IOException {
RandomAccessFile rf = new RandomAccessFile(file, "r");
for(int i = 0; i < 7; i++)
System.out.println(
"Value " + i + ": " + rf.readDouble());
System.out.println(rf.readUTF());
rf.close();
}
public static void main(String[] args)
throws IOException {
RandomAccessFile rf = new RandomAccessFile(file, "rw");
for(int i = 0; i < 7; i++)
rf.writeDouble(i*1.414);
rf.writeUTF("The end of the file");
rf.close();
display();
rf = new RandomAccessFile(file, "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();
display();
}
}
- 管道流
主要用于任务之间的通信。
18.8 标准I/O
- 从标准输入中读取
System.out, System.in, System.err
18.9 进程控制
18.10 新I/O
通道和缓冲器提高了读取的速度。
public class GetChannel {
private static final int BSIZE = 1024;
public static void main(String[] args) throws IOException {
FileChannel fc =
new FileOutputStream("d:/data/data.txt").getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes()));
fc.close();
fc = new RandomAccessFile("d:/data/data.txt", "rw").getChannel();
fc.position(fc.size());
fc.write(ByteBuffer.wrap("Some more".getBytes()));
fc.close();
fc = new FileInputStream("d:/data/data.txt").getChannel();
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
fc.read(buff);
buff.flip();
while (buff.hasRemaining()) {
System.out.print((char)buff.get());
}
}
}
- 转换数据
- 获取基本数据类型
ByteBuffer通过asShortBuffer等方法获取在改缓冲器上的视图,然后使用put()方法放入数据。 - 视图缓冲器
视图缓冲器可以让我们通过某个特定的基本数据类型的视窗查看其底层的ByteBuffer.
字节存放顺序:big endian 高位优先 (ByteOrder.BIG_ENDIAN),little endian 低位优先(ByteOrder.LITTLE_ENDIAN)。 - 用缓冲器操作数据
- 缓冲器的细节
- 内存映射文件
/**
* 内存映射文件
* @author Administrator
*
*/
public class LargeMappedFiles {
static int length = 0x8FFFFFF; // 128 MB
public static void main(String[] args) throws Exception {
MappedByteBuffer out =
new RandomAccessFile("test.dat", "rw").getChannel()
.map(FileChannel.MapMode.READ_WRITE, 0, length);
for(int i = 0; i < length; i++)
out.put((byte)'x');
print("Finished writing");
for(int i = length/2; i < length/2 + 6; i++)
printnb((char)out.get(i));
}
}
map()方法产生MappedByteBuffer可以指定映射文件的初始位置和映射区域长度。
map()的读写效率比stream高。
7. 文件加锁
/**
* 文件加锁
* @author Administrator
*
*/
public class FileLocking {
public static void main(String[] args) throws Exception {
FileOutputStream fos= new FileOutputStream("file.txt");
FileLock fl = fos.getChannel().tryLock();
if(fl != null) {
System.out.println("Locked File");
TimeUnit.MILLISECONDS.sleep(100);
fl.release();
System.out.println("Released Lock");
}
fos.close();
}
}
fos.getChannel()调用tryLock()或者lock()可以获得FileLock。
tryLock()是非阻塞式的,lock()是阻塞式的。fl.release()释放锁。
也可对映射部分加锁:
FileLock fl = fc.lock(start, end, false);
18.11 压缩
- 利用Gzip进行压缩
/**
* gzip压缩
* @author Administrator
*
*/
public class GZIPcompress {
public static void main(String[] args)
throws IOException {
BufferedReader in = new BufferedReader(
new FileReader("D:/data/data.txt"));
BufferedOutputStream out = new BufferedOutputStream(
new GZIPOutputStream(
new FileOutputStream("test.gz")));
System.out.println("Writing file");
int c;
while((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
System.out.println("Reading file");
BufferedReader in2 = new BufferedReader(
new InputStreamReader(new GZIPInputStream(
new FileInputStream("test.gz"))));
String s;
while((s = in2.readLine()) != null)
System.out.println(s);
}
}
- 利用zip进行多文件保存
/**
* zip进行多文件保存
* @author Administrator
*
*/
public class ZipCompress {
public static void main(String[] args)
throws IOException {
FileOutputStream f = new FileOutputStream("test.zip");
CheckedOutputStream csum =
new CheckedOutputStream(f, new Adler32());
ZipOutputStream zos = new ZipOutputStream(csum);
BufferedOutputStream out =
new BufferedOutputStream(zos);
zos.setComment("A test of Java Zipping");
// No corresponding getComment(), though.
File file = new File("D:/data/excel");
String[] list = file.list();
for(String arg : list) {
print("Writing file " + arg);
BufferedReader in =
new BufferedReader(new FileReader(arg));
zos.putNextEntry(new ZipEntry(arg));
int c;
while((c = in.read()) != -1)
out.write(c);
in.close();
out.flush();
}
out.close();
// Checksum valid only after the file has been closed!
print("Checksum: " + csum.getChecksum().getValue());
// Now extract the files:
print("Reading file");
FileInputStream fi = new FileInputStream("test.zip");
CheckedInputStream csumi =
new CheckedInputStream(fi, new Adler32());
ZipInputStream in2 = new ZipInputStream(csumi);
BufferedInputStream bis = new BufferedInputStream(in2);
ZipEntry ze;
while((ze = in2.getNextEntry()) != null) {
print("Reading file " + ze);
int x;
while((x = bis.read()) != -1)
System.out.write(x);
}
if(args.length == 1)
print("Checksum: " + csumi.getChecksum().getValue());
bis.close();
// Alternative way to open and read Zip files:
ZipFile zf = new ZipFile("test.zip");
Enumeration e = zf.entries();
while(e.hasMoreElements()) {
ZipEntry ze2 = (ZipEntry)e.nextElement();
print("File: " + ze2);
}
}
}