`

java.io

阅读更多
Java中比较丰富的I/O操作,使得Java能够被众多公司接受的一个优势之一。
数据流的概念和技术家奴啊了堆文件I/O的理解、处理以及操作。数据流指一定字节长度和方向的线性有序数据。虽然输入、输出数据都以线性有序字节流的形式存在,但这些数据流的内容可以构成不同文件格式:文本文件、二进制文件、对象文件、压缩文件等等。
Java中的I/0须知道以下内容:
文件的格式、文件内容、数据流方向、文件路径和缓冲。

1.基本知识
stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。在
Java的I/O中,所有的stream(包括Input和Out stream)都包括两种类型:
  • 以字节为导向的stream
  • 以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字
    节为导向的stream包括下面几种类型:
        1) input stream:
            1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
            2) StringBufferInputStream:把一个String对象作为InputStream
            3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作
            4) PipedInputStream:实现了pipe的概念,主要在线程中使用
            5) SequenceInputStream:把多个InputStream合并为一个InputStream
        2) Out stream
            1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
            2) FileOutputStream:把信息存入文件中
            3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
            4) SequenceOutputStream:把多个OutStream合并为一个OutStream
  • 以Unicode字符为导向的stream(我个人比较喜欢这个,easy,fast),表示以Unicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种类型:
  •     1) Input Stream
            1) CharArrayReader:与ByteArrayInputStream对应
            2) StringReader:与StringBufferInputStream对应
            3) FileReader:与FileInputStream对应
            4) PipedReader:与PipedInputStream对应
        2) Out Stream
            1) CharArrayWriter:与ByteArrayOutputStream对应
            2) StringWriter:无与之对应的以字节为导向的stream
            3) FileWriter:与FileOutputStream对应
            4) PipedWriter:与PipedOutputStream对应
    以字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现
    的功能相同,字是在操作时的导向不同。如CharArrayReader:和ByteArrayInputStream的
    作用都是把内存中的一个缓冲区作为InputStream使用,所不同的是前者每次从内存中读取
    一个字节的信息,而后者每次从内存中读取一个字符。
    负责字符流和字节流之间转换的工作有InputStreamReader和OutputStreamReader来完成。把一个以字节为导向的stream转换成一个以字符为导向的stream。


    stream添加属性:
    运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。但通过Fil
    terInputStream和FilterOutStream的子类,我们可以为stream添加属性。下面以一个例子
    来说明这种功能的作用。
    如果我们要往一个文件中写入数据,我们可以这样操作:
    FileOutStream fs = new FileOutStream(“test.txt”);
    然后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。但是,如
    果我们想实现“先把要写入文件的数据先缓存到内存中,再把缓存中的数据写入文件中”
    的功能时,上面的API就没有一个能满足我们的需求了。但是通过FilterInputStream和Fi
    lterOutStream的子类,为FileOutStream添加我们所需要的功能。

    FilterInputStream的各种类型
        用于封装以字节为导向的InputStream
           1) DataInputStream:从stream中读取基本类型(int、char等)数据。
           2) BufferedInputStream:使用缓冲区
           3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)
           4) PushbackInputStream:很少用到,一般用于编译器开发.
        用于封装以字符为导向的InputStream
           1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream
           2) BufferedReader:与BufferedInputStream对应
           3) LineNumberReader:与LineNumberInputStream对应
           4) PushBackReader:与PushbackInputStream对应
    FilterOutStream的各种类型
        用于封装以字节为导向的OutputStream
           1) DataIOutStream:往stream中输出基本类型(int、char等)数据。
           2) BufferedOutStream:使用缓冲区
           3) PrintStream:产生格式化输出
        用于封装以字符为导向的OutputStream
           1) BufferedWriter:与对应
           2) PrintWriter:与对应
    RandomAccessFile
           1) 可通过RandomAccessFile对象完成对文件的读写操作
           2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
           3) 可以直接跳到文件中指定的位置

    2. File
    File类是基础类,作为文件操作的对象。既可以是文件,也可以是目录。

    (1)四个静态常量:
    static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
    static char pathSeparatorChar 与系统有关的路径分隔符。
    static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
    static char separatorChar 与系统有关的默认名称分隔符

    其中,pathSeparator作为分隔符来区分不同的路径(在Windows下是;(分号),在Linux下是:(冒号))。separator是路径中使用的分隔符(在Windows下是\,在Linux下是/)。

    在File类中有很多有用的方法,可以参考阅读API。但是其中的如下方法要列出来说明下。
    String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
    String[] list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
    File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
    File[] listFiles(FileFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
    File[] listFiles(FilenameFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
    static File[] listRoots() 列出可用的文件系统根。


    在下面的例子中使用了上面表格中列出的内容。
    package com.java.io;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FilenameFilter;
    
    public class IO {
    	public static void main(String[] args) {
    		System.out.println("---------------------- Separator ----------------------");
    		System.out.println("pathSeparator: "+File.pathSeparator + "\t" + "separator: " + File.separator);
    		
    		System.out.println("---------------------- List Roots ----------------------");
    		File[] roots = File.listRoots();
    		for(File file : roots){
    			System.out.print(file + "\t");
    		}
    		System.out.println();
    		
    		System.out.println("---------------------- List ----------------------");
    		File file = new File("F:\\");
    		
    		System.out.print("List:\t\t\t\t");
    		String[] fileNames = file.list();
    		for(String name : fileNames){
    			System.out.print(name + "\t");
    		}
    		System.out.println();
    		
    		System.out.print("List(filter):\t\t\t");
    		String[] _fileNames = file.list(new FilenameFilter(){
    			@Override
    			public boolean accept(File file, String name) {
    				return file.isDirectory() && name.contains("E");//列出名字中有大写E的文件夹
    			}
    		});
    		for(String name : _fileNames){
    			System.out.print(name + "\t");
    		}
    		System.out.println();
    		
    		System.out.print("ListFiles():\t\t\t");
    		File[] files = file.listFiles();
    		for(File _file : files){
    			System.out.print(_file + "\t");
    		}
    		System.out.println();
    		
    		System.out.print("ListFiles(FilenameFilter):\t");
    		File[] _files = file.listFiles(new FilenameFilter(){
    			@Override
    			public boolean accept(File file, String name) {
    				return file.isDirectory() && name.contains("E");//列出名字中有大写E的文件夹
    			}
    		});
    		for(File _file : _files){
    			System.out.print(_file + "\t");
    		}
    		System.out.println();
    		
    		System.out.print("ListFiles(FileFilter):\t\t");
    		File[] __files = file.listFiles(new FileFilter(){
    			@Override
    			public boolean accept(File file) {
    				return file.isDirectory() && file.getName().contains("E");
    			}
    		});
    		for(File _file : __files){
    			System.out.print(_file + "\t");
    		}
    		System.out.println();
    	}
    }
    
    

    结果:
    ---------------------- Separator ----------------------
    pathSeparator: ; separator: \
    ---------------------- List Roots ----------------------
    C:\ D:\ E:\ F:\ G:\ H:\
    ---------------------- List ----------------------
    List: 579492bc12f33c12d7238760d8111512 Eclipse FavoriteVideo KwDownload Lectures RECYCLER System Volume Information
    List(filter): Eclipse RECYCLER
    ListFiles(): F:\579492bc12f33c12d7238760d8111512 F:\Eclipse F:\FavoriteVideo F:\KwDownload F:\Lectures F:\RECYCLER F:\System Volume Information
    ListFiles(FilenameFilter): F:\Eclipse F:\RECYCLER
    ListFiles(FileFilter): F:\Eclipse F:\RECYCLER

    3. 比较常用的I/O操作。
    FileInputStream/BufferedInputStream
    FileOutputStream/BufferedOutputStream/PrintStream
    FileReader/BufferedReader/InputStreamReader
    FileWriter/BufferedWriter/OutputStreamWriter

    Java中的管道模型,很好的对一层层的处理进行了封装,这使得Java的I/O处理使用起来相当灵活。一些常用的封装有:
    BufferedReader reader = new BufferedReader(new FileReader(new File("c:\\test.txt")));  //读取文件1
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("c:\\test.txt")));  //读取文件2
    InputStreamReader isr= new InputStreamReader(new FileInputStream(new File("c:\\test.txt")));  //读取文件3
    BufferedWriter writer = new BufferedWriter(new FileWriter(new File("c:\\test.txt")));  //写文件1
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("c:\\test.txt")));  //写文件2
    OutputStreamWriter osw= new OutputStreamWriter(new FileOutputStream(new File("c:\\test.txt")));  //写文件3
    System.setOut(new PrintWriter(new File("c:\\test.txt")));  //改变输出,将输出重定向到文件中

    4. 按照上面的介绍,如果想使用某一个管道模式来读写文件将会变得非常简单,只要查看下API文档,按照上面的结构很容易就能够实现自己想要的功能。
    下面是一个简单的例子。
    package com.java.io;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.LineNumberReader;
    import java.io.PrintStream;
    
    public class IO1 {
    	public static void main(String[] args) {
    		LineNumberReader reader = null;
    		try {
    			System.setOut(new PrintStream(new File("d:\\test2.txt")));
    			reader = new LineNumberReader(new FileReader(new File("d:\\test.txt")));
    			String line = "";
    			while((line = reader.readLine()) != null){
    				int number = reader.getLineNumber();
    				System.out.println(number + "\t" + line);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally{
    			try {
    				if(reader != null){
    					reader.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

    注:d:\test.txt 文件如附件,运行前该文件是存在的。运行程序之后,在d盘根目录下会生成一个test2.txt的文件,里面的内容如附件test_test2.rar。

    5. Object读写事例
    package com.java.io;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    public class OBJ_IO {
    	
    	public static void WriteOBJ(Person person, String fileName){
    		ObjectOutputStream oos = null;
    		try {
    			oos = new ObjectOutputStream(new FileOutputStream(new File(fileName)));
    			oos.writeObject(person);
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally{
    			if(oos != null){
    				try {
    					oos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	
    	public static Person readerPersonOBJ(String fileName){
    		Person person = null;
    		ObjectInputStream oos = null;
    		
    		try {
    			oos = new ObjectInputStream(new FileInputStream(new File(fileName)));
    			person = (Person)oos.readObject();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} finally{
    			if(oos != null){
    				try {
    					oos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    		return person;
    	}
    	
    	public static void main(String[] args) {
    		String fileName = "d:\\person.obj";
    		Person person = new Person("Eric",22);
    		
    		WriteOBJ(person, fileName);
    		person = readerPersonOBJ(fileName);
    		
    		System.out.println(person.getName());
    		System.out.println(person.getAge());
    	}
    }
    
    class Person implements Serializable{
    	private static final long serialVersionUID = -6018738718323071804L;
    	
    	private String name;
    	private int age;
    	
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	
    	public String getName() {
    		return name;
    	}
    	
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	public int getAge() {
    		return age;
    	}
    	
    	public void setAge(int age) {
    		this.age = age;
    	}
    	
    }
    

    结果:
    Eric
    22
    (注:在d盘会生成一个person文件,如附件person.obj.zip)

    6. RandomAccessFile类
    该类似于C++中的文件读取,可以查看相关API文档进行阅读。

    7. 压缩文件的读取操作。
    在java.util.zip目录下有GZIPInputStream GZIPOutputStream ZipInputStream 和 ZipOutputStream等类。以Zip来事例如何生成并读写Zip文件。
    package com.java.io;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    public class Zip {
    	
    	/**
    	 * 
    	 * @param content	要写到压缩包内文件的内容
    	 * @param fileName 	相当于最外面压缩包的名字
    	 * @param entryName	相当于压缩包内文件的名字
    	 */
    	public static void writeZip(String content, String fileName, String entryName){
    		ZipOutputStream zos = null;
    		try {
    			zos = new ZipOutputStream(new FileOutputStream(new File(fileName)));
    			zos.setMethod(ZipOutputStream.DEFLATED);//设置压缩方法
    			zos.putNextEntry(new ZipEntry(entryName));
    			byte[] bytes = content.getBytes();
    			int off = 0;
    			int len = bytes.length;
    			zos.write(bytes, off, len);
    			zos.finish();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally{
    			if(zos != null){
    				try {
    					zos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	
    	public static void readZip(String fileName){
    		ZipInputStream zis = null;
    		try {
    			File file = new File(fileName);
    			zis = new ZipInputStream(new FileInputStream(file));
    			while(zis.getNextEntry() != null){
    				byte[] bytes = new byte[1024];
    				int temp = -1;
    				int index = 0;
    				while((temp = zis.read()) != -1){
    					bytes[index++] = (byte)temp;
    				}
    				System.out.println(new String(bytes,0,index));
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public static void main(String[] args) {
    		String fileName = "d:\\test.zip";
    		String content1 = "This is test content";
    		
    		writeZip(content1, fileName, "content.txt");
    		readZip(fileName);
    	}
    }
    

    结果:
    This is test content
    (注:会在d盘生成一个test.zip文件。见附件test.zip)
    • 大小: 68.3 KB
    分享到:
    评论
    1 楼 www_JE 2010-11-17  
    楼主的帖子写的很好,关键部分都有,还有例子参考,对于我这样的新手来说太有用了~~~[

    相关推荐

      java.io.CharConversionException: isHexDigit处理

      Java.io.CharConversionException: isHexDigit 处理详解 Java.io.CharConversionException: isHexDigit 是 Java 中一种常见的异常,通常发生在传输数据时编码不正确或 URL 传值时出现问题。本文将对该异常进行详细...

      java.io.Reader 和 java.io.InputStream 的区别

      ### Java.io.Reader与Java.io.InputStream的关键差异解析 在深入探讨`java.io.Reader`与`java.io.InputStream`的具体差异之前,我们首先需要理解这两者在Java I/O操作中的基础角色。`java.io.Reader`和`java.io....

      java.io.InvalidClassException local class incompatible 处理方法

      ### Java.io.InvalidClassException Local Class Incompatible 解决方案 在Java序列化过程中,经常会遇到`java.io.InvalidClassException`异常,特别是在序列化类时如果类的版本与反序列化环境中的类版本不一致的...

      java.io.FileNotFoundException: *****(Too many open files)

      在Java编程中,"java.io.FileNotFoundException: ***** (Too many open files)" 是一个常见的错误,意味着程序尝试打开的文件数量超过了操作系统的限制。这个错误通常出现在处理大量文件或长时间运行的程序中,尤其...

      Java.nio 与Java.io比较

      在探讨Java.nio与Java.io之间的比较时,我们首先需要理解这两个包在Java编程语言中的核心作用和它们各自的优势。Java.io和Java.nio是Java中处理输入/输出操作的两个主要框架,它们各自拥有独特的特性和应用场景。 #...

      java.io包讲解

      `java.io.Writer`是所有字符输出流的父类,它定义了一些基本方法,如写入单个字符、写入字符数组等。 - `public void write(int c)`:向流中写入单个字符。 - `public void write(char[] cbuf)`:将字符数组中的...

      import java.net.*;import java.io.*;

      import java.io.*; public class udptest { ///创建一个数据包套接字对象ds,并且指定连接的端口号 ///创建一个数据包对象dp ///指定一个字节数组,用来存储接受的数据 public static void rev() { try { ...

      深入理解Java中的两种Stream:`java.util.stream.Stream`与`java.io.Stream`

      理解java.util.stream.Stream与java.io.Stream的区别对于Java开发者来说非常重要。这两种Stream在Java生态系统中都扮演着重要的角色,但它们服务于不同的目的。正确选择和使用这两种Stream,可以帮助你编写更高效、...

      java.io的基础应用

      在Java中,IO操作主要分为字节流和字符流两大类,分别由`java.io.InputStream`和`java.io.OutputStream`以及`java.io.Reader`和`java.io.Writer`作为基类。字节流处理的是8位的字节,而字符流处理的是16位的Unicode...

      import java.io.*; public class FirstPart{ public static void main(String[] args) throws Exception{ System.out.print("The input Fahrenheit is "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int f = Integer.parseInt(br.re

      import java.io.*; public class FirstPart{ public static void main(String[] args) throws Exception{ System.out.print("The input Fahrenheit is "); BufferedReader br = new BufferedReader(new ...

      java.io:clojure.java.io 的 JK7 java.nio.file.Path 兼容性

      java.io clojure.java.io 的 JK7 java.nio.file.Path 兼容性依赖信息该库托管在 Releases 上。 依赖: [me.moocar/java.io " 0.1.0 " ]用法是 JDK7 中引入的文件路径的抽象。 这个库提供了和 Paths 之间的兼容性。 ...

      java_io.rar_java 文件操作_java 读取 本地文件_java.io转动_文件操作

      本资源“java_io.rar”提供了关于如何在Java中进行文件操作的示例代码,包括读取、移动、删除和复制文件等常见任务。我们将深入探讨这些主题,以便更好地理解Java I/O API的使用。 首先,让我们从读取本地文件开始...

      java.io包详细解说

      【Java IO包详解】 Java IO包是Java标准库中的核心组件之一,主要用于处理输入和输出操作。这个包包含了大量类和接口,它们提供了各种输入输出流、字符编码、数据转换以及文件操作等功能。Java IO的设计采用了...

      android 串口驱动

      import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream...

      gnu.io.SerialPort( rxtx-2.1.7.jar)

      gnu.io.CommDriver.class gnu.io.CommPort.class gnu.io.CommPortEnumerator.class gnu.io.CommPortIdentifier.class gnu.io.CommPortOwnershipListener.class gnu.io.Configure.class gnu.io.I2C.class gnu.io.I2...

      socket.io,socket.io-client下载

      1. **服务器端设置**:在Node.js项目中,导入`socket.io`模块,初始化服务器并监听特定端口,然后使用`io.on('connection', (socket) => {})`来处理新连接和事件。 2. **客户端连接**:在Java或Android应用中,导入...

      sun.io.CharToByteConverter支持类

      项目工程中用到jdk1.6相关方法,可以使用,但是升级到jdk1.8以后,编译出现java.lang.NoClassDefFoundError: sun/io/CharToByteConverter错误,后经查询,是jdk1.8版本中已经从sun.io.*中进行去除。网上找来了相关...

      java.io 学习

      使用Date 类获取系统当前时间 Calendar类的使用 使用 Random 类的对象生成随机数 Collection 类的对象的使用 HashMap 对象以键和值的关系形式存储数据

      gnu.io.SerialPort( rxtx-2.1.7.jar)串口通讯

      串口通讯需要的jar包,gnu.io.SerialPort; gnu.io.CommPortIdentifier; gnu.io.SerialPort; gnu.io.SerialPortEvent; gnu.io.SerialPortEventListener; gnu.io.UnsupportedCommOperationException; Copy RXTXcomm...

    Global site tag (gtag.js) - Google Analytics