Java I/O总结

近日做了老师布置的Java作业,其中有不少关于I/O流的内容,做起来发现一头雾水,于是上网找了一些资料,做些简单总结.

首先说一下数据流的概念,数据流就是连续不断的数据集合,当数据写入程序或者从程序输出时,数据会按先后顺序形成数据流,所以在用流读取或者写入时,我们也是按顺序的。数据流有起点终点,起点终点可以是文件,内存,或者网络连接

数据流分类:

                            (1)字节流:即数据流中最小单位是字节(byte)。

                             (2)字符流:数据中最小单位是字符,Java中的Unicode编码一个字符占两个字节。

I/O体系又分为流式和非流式,如下图:

           

以上是常用的主要类,功能简述如下:

  1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
  2. InputStream(字节流,二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
  3. OutputStream(字节流,二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
  4. Reader(字符流,文本格式操作):抽象类,基于字符的输入操作。
  5. Writer(字符流,文本格式操作):抽象类,基于字符的输出操作。
  6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作

I/O流

I/O流

 由上图不难得知,流中主要处理以下几个类型:文件(File衍生类),字节数组(Byte相关衍生类),字符数组(Char衍生类),字符串(String相关),而网络数据流各个子类都会参与其中。

InputStream

InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据的,且数据单位为字节(8bit);

InputStream中有三种重载的read方法用于读取数据:

  • public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
  • public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
  • public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
  • public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
  • public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
  • public int close( ) :使用完后,必须对我们打开的流进行关闭。

几个子类的作用简介:

  1. FileInputStream:把一个文件作为InputStream,实现对文件的读取操作
  2. ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
  3. StringBufferInputStream:把一个String对象作为InputStream
  4. PipedInputStream:实现了pipe的概念,主要在线程中使用
  5. SequenceInputStream:把多个InputStream合并为一个InputStream
  6. FilterInputStream :用来“封装其它的输入流,并为它们提供额外的功能”。

OutputStream

与InputStream相对应,有三个重载的write方法,用于数据的输出

  • public void write(byte b[ ]):将参数b中的字节写到输出流。
  • public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
  • public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
  • public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
  • public void close( ) : 关闭输出流并释放与流相关的系统资源。

几个子类作用简介:

  1. FileOutputStream:把信息存入文件中
  2. ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
  3. StringBufferOutputStream:把一个String对象作为InputStream
  4. PipedOutputStream:实现了pipe的概念,主要在线程中使用
  5. SequenceOutputStream:把多个OutStream合并为一个OutStream
  6. FilterOutputStream :用来“封装其它的输出流,并为它们提供额外的功能”。

以上FilterOutputStream本身也是一个超类,其中的缓冲流BufferedOutputStreamBufferedInputStream在读写数据时减少直接访问数据源的次数,提高效率。

创建BufferedInputStream类对象格式:

InputStream is=new BufferedInputStream(InputStream in);              //默认缓冲区,大小为8192字节

InputStream is=new BufferedInputStream(InputStream in,int size);   //自定义缓冲区,大小为size

BufferedOutputStream创建格式与上方大同小异。

Reader类和Writer类用法和上面两种差不多,若要处理的对象全都是文本数据则可以选用字符流,字节流通用。

有两个需要注意的:

  1. InputStreamReader : 从输入流读取字节,在将它们转换成字符。
  2. BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。

如何选择I/O流

  1. 确定是输入还是输出
    输入:输入流 InputStream Reader
    输出:输出流 OutputStream Writer
  2. 明确操作的数据对象是否是纯文本
    是:字符流 Reader,Writer
    否:字节流 InputStream,OutputStream
  3. 明确具体的设备。
    • 文件:
      读:FileInputStream,, FileReader,
      写:FileOutputStream,FileWriter
    • 数组:
      byte[ ]:ByteArrayInputStream, ByteArrayOutputStream
      char[ ]:CharArrayReader, CharArrayWriter
    • String:
      StringBufferInputStream(已过时,因为其只能用于String的每个字符都是8位的字符串), StringReader, StringWriter
    • Socket流
      键盘:用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印
  4. 是否需要转换流
    是,就使用转换流,从Stream转化为Reader、Writer:InputStreamReader,OutputStreamWriter
  5. 是否需要缓冲提高效率
    是就加上Buffered:BufferedInputStream, BufferedOuputStream, BufferedReader, BufferedWriter

RandomAccessFile使用示例

import java.io.*;
import java.util.Scanner;
class FileCopy {
	public static void main(String[] args) throws IOException {
		Scanner scan=new Scanner(System.in);
		System.out.println("请输入源文件名和目标文件名:");
		String oldFileName=scan.nextLine();
		String newFileName=scan.nextLine();
		File oldFile=new File("C:\\Users\\lee\\Desktop",oldFileName);
		File newFile=new File("C:\\Users\\lee\\Desktop",newFileName);
		try {
			RandomAccessFile rfile=new RandomAccessFile(oldFile,"r");
			RandomAccessFile nfile=new RandomAccessFile(newFile,"rw");
			int d=-1;
			while((d=rfile.read())!=-1) {
				nfile.write(d);
			}
			rfile.close();
			nfile.close();
		}catch(FileNotFoundException e){
				System.out.println("找不到文件");		
		}
		
	}
}

 BufferedInputStream使用示例

import java.io.*;
import java.util.Scanner;

public class testBufferInputStream {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		File file=new File("C:\\Users\\lee\\Desktop","BufferInput.txt");
		String a;
		Scanner scan=new Scanner(System.in);
		BufferedOutputStream fos ;
		try {
			fos=new BufferedOutputStream(new FileOutputStream(file));
			System.out.println("请输入字符:");
			while(!"quit".equals((a=scan.nextLine()))) {
				System.out.println("请输入字符:");
				fos.write(a.getBytes());
				fos.flush();
				}
			
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}catch(IOException e) {
			e.getMessage();
		} 
		
			
	}

}

引荐原文出处:http://www.importnew.com/23708.html

猜你喜欢

转载自blog.csdn.net/qq1084235321/article/details/83817998