频道栏目
首页 > 资讯 > Java > 正文

Java编程思想学习讲解之Java I/O系统

18-07-19        来源:[db:作者]  
收藏   我要投稿

第十八章 Java I/O系统

标签 : Java编程思想


对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统一项艰难的任务。

I/O系统不仅要与各种终端打交道,比如输入输出终端,网络连接,文件系统等,并且还需要多种方式,比如顺序,缓冲,二进制等。

Java中提供了大量的类来实现文件操作。

如果缺乏历史的眼光,很快我就会对什么时候该使用哪些类,以及什么时候不该使用他们而搞到迷惑。

18.1 File类

File这个名字并非指代文件,它既能代表一个特定的文件,又能代表一个目录下的文件集合。如果指代的是文件集合的话,可以调用list()方法得到一个包含该目录下文件集合的数组。

18.1.1 目录列表器

查看一个目录列表,可以有两种方法使用File对象:

* 调用不带参数的list()方法获取全部文件集合;

* 使用“过滤器”获得特定类型文件的文件集合。

package com.io;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;

/**
 * @author zhulongkun20@163.com
 * @since 13:34 2018/7/18
 */
public class DirList {
 public static void main(String[] args) {
  File path = new File(".");
  String[] list;
  if (args.length == 0) {
list = path.list();
  } else {
list = path.list(new DirFilter(args[0]));
  }
  assert list != null;
  Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
  for (String dir : list) {
System.out.println(dir);
  }
 }
}

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

output:

.idea
.vscode
out
ThinkInJavaDemo

Process finished with exit code 0

匿名内部类改写:

package com.io;

import java.io.File;
import java.io.FilenameFilter;
import java.util.regex.Pattern;

/**
 * @author zhulongkun20@163.com
 * @since 13:53 2018/7/18
 */
public class DirListA {
 public static FilenameFilter filenameFilter(final String regex) {
  return new FilenameFilter() {
private Pattern pattern = Pattern.compile(regex);

@Override
public boolean accept(File dir, String name) {
 return pattern.matcher(name).matches();
}
  };
 }

 public static void main(String[] args) {
  /**
* do something.
*/
 }
}

为了减少DirList类与FilenameFilter类之间的耦合,可以改写如下:

package com.io;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;

/**
 * @author zhulongkun20@163.com
 * @since 13:58 2018/7/18
 */
public class DirListB {
 public static void main(String[] args) {
  File path = new File(".");
  String[] list;
  if (args.length == 0) {
list = path.list();
  } else {
list = path.list((dir, name) -> {
 Pattern pattern = Pattern.compile(args[0]);
 return pattern.matcher(name).matches();
});
  }
  assert list != null;
  Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
  for (String dir : list) {
System.out.println(dir);
  }
 }
}

18.1.2 目录使用工具

文件操作在实际开发中是非常常用的,有一个实用的文件工具类会大大提高开发效率。

下面的方法通过一个特定的正则表达式使用local()方法和walk()方法产生特定目录下的整个目录书中的所有文件构成List。

File.listFiles()产生File数组。

18.1.3 目录的检查及创建

可以使用File对象来表示已经存在的文件或者路径,也可以用来创建新的目录或文件。一些File类的常用方法:

canRead(); canWrite() length(); getName(); getAbsolutelyPath(); lastModified(); getParent(); renameTo(new File());

18.2 输入和输出

Java中“流”类库让人迷惑的主要原因就在于:创建单一的结果流,却需要创建多个对象。

18.2.1 InputStream类型

InputStream的作用是用来表示那些从不同数据源产生的输入的类。

InputStream类型:

功能 构造参数及使用
ByteArrayInputStream 允许将内存的缓冲区当做InputStream使用 缓冲区,字节将从中取出,作为一种数据源,将其与FilterInputStream对象相连以提供有用接口
StringBufferInputStream 将String转换成InputStream 底层实际使用StringBuffer作为数据源,将其与FilterInputStream对象相连以提供有用接口
FileInputStream 用于从文件读取信息 字符串表示文件名,文件或FileDescriptor对象
PipedInputStream 产生用于写入相关PipedOutputStream的数据 PipedOutputStream作为多线程数据源,将其与FilterInputStream对象相连以提供有用接口
FilterInputStream 抽象类,作为“装饰器”的接口,为其他InputStream类提供有用功能 。。

OutputStream类型:

功能 构造参数及使用
ByteOutputStream 在内存中创建缓冲区,数据的暂时存储区域 缓冲区初始化大小,制定数据的目的地,将其与FilterOutputStream对象相连以提供有用接口
FileOutputStream 用于将信息写至文件 字符串表示文件名,文件或者FileDescriptor对象,将其与FilterOutputStream对象相连以提供有用接口
FilterOutputStream 抽象类,作为“装饰器”的接口,为其他OutputStream提供有用功能 。。

18.3 添加属性和有用的接口

18.3.1 通过FilterInputStream从InputStream输入

FilterInputStream类型:

功能 构造器和参数
DataInputStream 与DataOutputStream搭配使用 InputStream包含用于读取本类型数据的全部接口
BufferedInputStream 可以防止每次读取时都进行实际写操作,代表使用“缓冲区” InputStream,可以指定缓冲区大小
LineNumberInputStream 跟踪输入流中的行号,可调用getLineNumber()和setLineNumber(int) 仅增加了行号
PushbackInputStream 具有“能弹出一个字节的缓冲区”因此可以将读到的最后一个字节回退 通常作为编译器的扫描器,存在的原因是因为Java编译器的需要,极不常用

18.3.2 通过FilterOutputStream向OutputStream写入

FilterOutputStream类型:

类型 功能 构造参数及使用
DataOutputStream 与DataInputStream搭配使用 OutputStream包含用于写入基本类型数据的全部接口
PrintStream 用于产生格式化输出,其中DataOutputStream处理数据的存储,PrintStream处理显示 OutputStream,可以用boolean值只是是否在每次换行时都清空缓冲区应该是对OutputStream对象的final封装,可能会经常使用到他
BufferedOutputStream 使用它以避免每次发送数据时都要进行实际的写操作,代表“使用缓冲区”,可以调用flush()清空缓冲区 OutputStream可以指定缓冲区大小,本质上不提供接口,只不过是向进程中添加缓冲区所必须的,与接口对象搭配

18.4 Reader和Writer

18.4.1 数据的来源和去处

来源 去处
InputStream OutputStream
FileInputStream FileOutputStream
StringBufferInputStream StringBufferOutputStream
ByteArrayInputStream ByteOutputStream
PipedInputStream PipedOutputStream

18.6 典型的I/O流使用方式

18.6.1 缓冲输入文件

package com.io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author zhulongkun20@163.com
 * @since 21:22 2018/7/18
 */
public class BufferedInputFile {
 public static String read(String fileName) throws IOException {
  BufferedReader in = new BufferedReader(new FileReader(fileName));
  String s;
  StringBuilder stringBuilder = new StringBuilder();
  while ((s = in.readLine()) != null) {
stringBuilder.append(s).append("\n");
  }
  in.close();
  return stringBuilder.toString();
 }

 public static void main(String[] args) throws IOException {
  System.out.println(read("BufferedInputFile.java"));
 }
}

18.6.2 从内存输入

package com.io;

import java.io.IOException;
import java.io.StringReader;

/**
 * @author zhulongkun20@163.com
 * @since 21:28 2018/7/18
 */
public class FormattedMemoryInput {
 public static void main(String[] args) throws IOException {
  StringReader in = new StringReader(BufferedInputFile.read("demo.java"));
  int c;
  while ((c = in.read()) != -1) {
System.out.println((char) c);
  }
 }
}
package com.io;

import java.io.*;

/**
 * @author zhulongkun20@163.com
 * @since 21:32 2018/7/18
 */
public class TestEOF {
 public static void main(String[] args) throws IOException {
  DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("")));
  while (in.available() != 0) {
System.out.println((char) in.readByte());
  }
 }
}

18.6.4 基本的文件输出

package com.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;

/**
 * @author zhulongkun20@163.com
 * @since 21:35 2018/7/18
 */
public class BasicFileOutput {
 static String file = "BasicFileOutput.out";

 public static void main(String[] args) throws IOException {
  BufferedReader in = new BufferedReader(new StringReader(BufferedInputFile.read("")));
  PrintWriter out = new PrintWriter(file);
  int lineCount = 1;
  String s;
  while ((s = in.readLine()) != null) {
out.println(lineCount++ + ":" + s);
  }
  out.close();
  System.out.println(BufferedInputFile.read(file));
 }
}
相关TAG标签
上一篇:Java 多线程三大核心点实例讲解
下一篇:PHP 身份证验证功能代码实现
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站