概述
Java中输入、输出的处理通过java.io包下的类和接口来支持,在这个包下主要包括输入、输出两种IO流,每种输入、输出流又可以分为字节流和字符流。字节流以字节为单位来处理输入输出,字符流则以字符为单位。除此之外,Java的IO流使用了一种装饰器设计模式,它将IO流分成底层节点流和上层处理流。节点流用于和底层物理存储节点直接关联,不同物理节点获取节点流的方式可能存在一定差异,但程序可以把不同的物理节点流包装成统一的处理流,从而允许程序使用统一的输入、输出代码来读取不同物理存储节点的资源。
● 输入流和输出流 (按照数据流的方向)
Java的输入流主要由InputStream和Reader作为基类,输出流主要由OutputStream和Writer作为基类。
● 字节流和字符流 (按照处理数据的单位不同)
字节流和字符流的用法几乎完全一致,区别在于它们所操作的数据单元不同,字节流(8位)、字符流(16位),字节流主要由InputStream和OutputStream作为基类,字符流主
要由Reader和Writer作为基类。
● 节点流和包装流(处理流) (按照功能的不同)
从/向一个特定的I/0设备(磁盘、网络等)读写数据的流称为节点流,也常被称为低级流。
处理流则对于一个已存在的节点流进行连接或封装,常被称为高级流(装饰器设计模式)。
处理流的功能主要体现在:
1、性能的提高:主要以增加缓冲的方式来提高输入/输出的效率
2、操作的便捷:提供了系列便捷的方法来一次输入/输出大批量内容
JDK 1.4以后,Java在java.nio包下提供了系列的全新API,这就是Java新IO(new io)。用以更高效的进行输入、输出操作的处理。
Java I/O 体系大体图
File类
public class File extends Object
implements Serializable, Comparable<File>,文件和目录路径名的抽象表示形式。
File类是java.io包下代表与平台无关的文件和目录,在程序中用来操作文件和目录。使用文件路径字符串来创建File示例,该文件路径字符串既可以是绝对路径,也可以是相对路径。File能新建、删除和重命名文件和目录,但是不能访问文件内容本身。访问文件内容本身的操作需要使用IO流。
package cn.nevo.io; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class DirList2 { public static void main(String[] args) { //必须要保证父目录hello的存在 File path = new File("c:\\hello\\hello.txt"); if(!path.getParentFile().exists()) { path.getParentFile().mkdir(); } if(!path.exists()) { try { path.createNewFile(); System.out.println("文件创建成功!"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } byte[] s = new byte[]{'h', 'e', 'l', 'l', 'o'}; try { OutputStream out = new FileOutputStream(path); out.write(s); } catch (Exception e) { e.printStackTrace(); } } }
package java.io; public interface FilenameFilter { boolean accept(File dir, String name); }
package cn.nevo.io; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; import java.util.regex.Pattern; //查看目录列表 public class DirList { public static void main(String[] args) { //"/"代表该资源所处的根目录,此处为F:\ //"."代表该资源所在项目所处目录,此处为F:\workspace\JavaIoTest\. File path = new File("."); //返回此抽象路径名的绝对路径名字符串。 System.out.println(path.getAbsolutePath()); String[] list; //没有指定运行参数,获取File对象包含的全部列表 if(args.length == 0) { //list()方法返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。 list = path.list(); } //获取受限制列表 else { //list(FilenameFilter filter)返回满足指定过滤器条件的目录和文件列表 //args:".*\.project" //list方法会为此目录对象下的每个文件名调用accept方法,来判断该文件是否包含再内 list = path.list(new DirFilter(args[0])); } //对查询结果按字母排序 Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); //输出数组列表 for(String dirItem : list) { System.out.println(dirItem); } } } //实现FilenameFilter接口的类实例可用于过滤文件名 class DirFilter implements FilenameFilter { private Pattern pattern; public DirFilter(String regex) { //compile(String regex)将给定的正则表达式编译到模式中。 this.pattern = Pattern.compile(regex); } @Override public boolean accept(File dir, String name) { //创建匹配给定输入与此模式的匹配器,尝试将整个区域与模式匹配。 //当且仅当整个区域序列匹配此匹配器的模式时才返回 true boolean flag = pattern.matcher(name).matches(); System.out.println(flag); return flag; } }
package cn.nevo.io; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; import java.util.regex.Pattern; public class DirList3 { public static void main(final String[] args) { File path = new File("."); String[] list; if(args.length == 0) { list = path.list(); } else { list = path.list(new FilenameFilter() { //参数args必须是final的,内部类要求 //pattern知道匹配模式 private Pattern pattern = Pattern.compile(args[0]); @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); } Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); for(String dirItem : list) { System.out.println(dirItem); } } }
package cn.nevo.io; import java.io.File; public class MakeDirectories { //无参数指定 public static void usage() { System.err.println( "Usage:MakeDirectories path1 ... \n" + "Creates each path\n" + "Usage:MakeDirectories -d path1 ... \n" + "Deletes each path\n" + "Usage:MakeDirectories -r path1 path2\n" + "Renames from path1 to path2" ); System.exit(1); } public 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) { //无参数输入,调用usage,给出提示 if(args.length < 1) { usage(); } //重命名文件,指定三个输入参数 if(args[0].equals("-r")) { if(args.length !=3) { usage(); } File old = new File(args[1]), rname = new File(args[2]); old.renameTo(rname); fileData(old); fileData(rname); return; } //新建和删除 int count = 0; boolean del = false; if(args[0].equals("-d")) { count ++; del = true; } count--; while(++count < args.length) { File f = new File(args[count]); if(f.exists()) { System.out.println(f + " exists"); if(del) { System.out.println("deleting..." + f); f.delete(); } }else { //不存在 if(!del) { f.mkdirs(); System.out.println("created " + f); } } fileData(f); } } }
public class FileInputStreamTest { public static void main(String[] args) { InputStream in = null; try { in = new FileInputStream(".\\src\\cn\\nevo\\io\\FileInputStreamTest.java"); byte[] by = new byte[1024]; int hasRead = 0; while((hasRead = in.read(by)) > 0) { System.out.println(new String(by, 0, hasRead)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }
public class FileOutputStreamTest { public static void main(String[] args) { FileInputStream input = null; FileOutputStream output = null; try { //字节输入流 input = new FileInputStream(".\\src\\cn\\nevo\\io\\FileOutputStreamTest.java"); output = new FileOutputStream(".\\FileOutputStreamTest.txt"); byte[] by = new byte[1024]; int hasRead = 0; while((hasRead = input.read(by)) > 0) { output.write(by, 0, hasRead); } System.out.println("文件复制成功!"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } finally { try { input.close(); output.close(); }catch (IOException e) { e.printStackTrace(); } } } }
//处理流 public class PrintStreamTest { public static void main(String[] args) { PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream("text.txt"); ps = new PrintStream(fos); ps.println("处理流示例"); ps.append("PrintStream!"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
public class KeyInTest { public static void main(String[] args) { //java使用System.in代表标准输入,是InputStream(字节流)的实例 BufferedReader br = null; try { //将字节流转换为字符流 InputStreamReader isr = new InputStreamReader(System.in); //将普通的字符流包装成缓冲流 br = new BufferedReader(isr); String buffer; while((buffer = br.readLine()) != null) { if(buffer.equals("exit")) { System.exit(1); } //打印读取内容 System.out.println(buffer); } } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } }
public class RedirectOut { public static void main(String[] args) { //问重定向标准输出之前输出到控制台 System.out.println("输出到控制台"); PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream("out.txt"); ps = new PrintStream(fos); //重定向标准输出到PrintStream System.setOut(ps); //此时便不再输出到控制台 System.out.println("不再输出到控制台"); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { ps.close(); } } }
public class RandomAccessFileTest { public static void main(String[] args) { File file = new File(".\\src\\cn\\nevo\\io\\RandomAccessFileTest.java"); RandomAccessFile raf = null; try { //以只读方式打开一个RandomAccessFile对象 raf = new RandomAccessFile(file, "r"); //文件指针的初始位置0 System.out.println(raf.getFilePointer()); //从文件指针为300的位置开始读 raf.seek(300); int hasRead = 0; byte[] by = new byte[1024]; while((hasRead = raf.read(by)) > 0) { System.out.println(new String(by, 0, hasRead)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } finally { try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } }