Java I/O流的认识

// java I/O系统
// 程序主要是操作数据,在运行时,这些数据都必须位于内存中,并且属于特定的类型,程序才能操纵他们,
// 介绍如何从数据源中读取数据以供程序处理,以及如何把程序处理后的数据写到数据目的地中,数据目的地也称为数据汇
// 在java中,把一组有序的数据序列称为流,根据操作的类型,可以把流分为输入流和输出流两种
// 数据源包括文件,内存,键盘,数据汇包括文件,内存,控制台
// 如果数据流中最小的数据单元是字节,那么称这种流为字节流,如果数据中最小的数据单元是字符,那么称这种流为字符流
// inputStream和OutPutStream表示字节流,Reader和Write表示字符流,
// inputStream是抽象类,不能实例化,InputStream类提供了一系列和读取数据有关的方法:
// int read():从输入流读取数据,有三种重载形式:
// 1. int read(),读取一个8位的字节,把他转换为0-255之间的整数,并返回这一整数,例如9就是9,而-9就是247,遇到输入流的结尾,则返回-1
// 2. int read(byte[] b),出去若干个字节,把他们保存到参数b指定的字节数组中,返回的整数表示读取的字节数,遇到输入流的结尾,返回-1
// 3. int read(byte[] b,int off,int len),读取若干个字节,把他们保存到b指定的字节数组中,参数off指定在字节数组中开始保存数据的起始下标
// 参数len指定读取的字节数目,返回的整数表示实际读取的字节数,遇到输入流的结尾,则返回-1
// 第一种读取一个字节,后面两种读取若干字节,后面两个read方法可以减少进行物理读文件或键盘的次数,因此提高I/O操作的频率
// void close() 关闭输入流,释放与流有关的系统资源
// int available() 返回可以从输入流中读取的字节数目
// skip(long n) 从输入流中跳过参数n指定数目的字节
// boolean markSupported(),void mark(int readLimit),void reset();如果要从流中重复读入数据,可以通过这样实现
// outputStream也提供了一系列写数据有关的方法
// void write(int b); 写一个字节
// void write(byte[] b) 把参数b指定的字节数组中的所有字节写到输出流
// void write(byte[] b,int off,int len) 把参数b指定的字节数组中的若干字节写到输出流,参数off指定字节数组的起始下标
// 从这个位置开始输出由参数len指定数目的字节
// void close();关闭输出流,
// void flush();outputStream类本身的flush()方法不执行任何操作,他的带有缓冲区的子类(BufferedOutputStream和printStream)
// 类覆盖了flush方法,通过缓冲区的输出流写数据时,数据先保存在缓冲区中,积累到一定程度才真正写到输出流中,缓冲区通常用字节数组实现,实际上是指
// 一块内存空间,flush()方法强制把缓存区内的数据写到输出流中
// 这样可以减少运送的次数,最后把关闭流的操作放在finally代码块中,
// 输入流:inputStream的直接子类和间接子类:
// 直接子类:ByteArrayInputStream(byte[] buf) 把字节数组转换为输入流,其本身采用了适配器设计模式,把字节数组类型转换为输入流类型,使的程序能够对字节数组进行读操作
//        FileInputStream(File file) 参数file指定文件数据源,FileInputStream(String name)参数name指定文件数据源,name包含了文件路径信息
//  StringBufferInputStream(String s) 类本身采用了适配器设计模式,把字符串类型转换为输入流类型,使得程序代码能够对字符串进行操作,本意是把字符串转换为字节流,但是这个类仅仅使用了字符编码的低8位,不能
//        把字符串中的所有字符(比如中文字符)正确转换为字节,因此这个类已经废弃,取而代之的是StringReader类
//        PipedInputStream 管道输入流,通常由一个线程向管道输出流写数据,由另一个线程从管道输入流中读取数据,两个线程可以用管道来通信
//        SequenceInputStream 顺序输入流,可以将几个输入流串联在一起,合并为一个输入流,当通过这个类来读取数据时,他会依次从所有被串联的输入流中读取数据,对程序来说,就好像是对同一个流操作
//        构造方法:SequenceInputStream(Enumeration e) 在枚举类型的参数e中包含了若干需要被串行的输入流 SequenceInputStream(InputStream s1,InputSteam s2)参数s1和s2代表两个需要被串行的输入流,顺序是先读s1中的数据,再读取s2中的数据
//        FilterInputStream 过滤输入流,在FIleInputStream和ByteArrayInputStream等具体的输入流都是按照流中字节的先后顺序读取字节,假如希望进一步扩展读数据的功能,一种是创建FileInputStream等输入流的子类,会大大增加输入流类的数目,使输入流的层次结构更加复杂
//        还有一种就是创建输入流的装饰器,他本身也继承了InputStream类,还可以用来装饰其他的输入流类,I/O类库中的FilterInputStream类就是一种装饰器,
// 间接子类    FilterInputStream是一种用于扩展输入流功能的装饰器,他有以下几个子类:
//        DataInputStream 与DataOutputStream搭配使用,可以按照与平台无关的方式从流中读取基本类型(int,char,long)的数据,由于FIlterInputStream的构造方法是protected访问级别,因此外部程序不能创建这个类本身的实例,FilterInputStream及其子类的构造方法都有一个InputStream类型的参数,该参数指定需要被修饰的输入流
//        DataOutputStream类有writeUTF,writeChar,writeLong和对应的readLong,readChar,readUTF
//        LineNumberInputStream,这个类已经被废弃,因为他处理的是字节流,不能正确解析流中的换行字符,在需要为输入流中的数据进行编号的场合,应该用LineNumberReader类取代LineNumberInputStream类
//        BufferedInputStream,覆盖了被装饰的输入流的读数据行为,利用缓冲区来提高读数据的效率,BufferedInputStream类先把一批数据读入到缓冲区,接下来read()方法只需要从缓冲区内获取数据,就能减少
//        物理性读取数据的次数,BufferedInputStream(InputStream in)  BufferedInputStream(InputStream in, int size) in指定被装饰的输入流,参数size指定缓冲区的大小,以字节为单位
//        PushbackInputStream类有一个后推缓冲区,用于存放已经读入的当前字节,在需要根据当前读入的字节来判断该对下一个字节做什么操作的时候,这个类很有用
// 输出流 所有的输出流都是OutputStream类的直接或者间接子类 
// 直接子类:ByteArrayOutputStream ,FileOutputStream,FilterOutPutStream,
// 间接子类:DataOutPutStream,BufferedOutputStream,PrintStream
// 用过滤输出流来装饰其他输出流时,只要关闭过滤输出流,他的close方法就会调用被装饰的输出流的close方法,此外,过滤输出流的close方法还会调用自身以及被装饰流的flush()方法,确保缓冲区内还有数据,把这些数据写到数据汇中
//        PrintStream输出流和DataOutputStream一样,也能输出格式化的数据,print(int i), print(String s)向输出流写入一个String类型的数据,采用本地操作系统的默认字符编码,
//        println(long l)向输出流写入一个long类型的数据和换行符,println(String s)向输出流写入一个String类型的数据和换行符,采用本地操作系统默认的字符编码
//        使用PrintStream类时有以下注意事项:
//        1. 每个print()方法都和一个println()方法对应. 2. PrintStream的println(String s)和DataOutputStream的writeUTF(String s)一样,都能输出字符串,两者区别在于:前者采用本地操作系统默认的字符编码
//        而后者 采用java语言的UTF-8字符编码,用DataOutputStream的writeUTF()方法输出的字符串只能用DataInputStream的readUTF()方法读取,这样才能得到正确的数据
//        3. PrintStream的所有print()和println()方法没有声明抛出IOException,客户程序可以通过PrintStream的checkError()方法来判断写数据是否成功,如果返回true,就表示遇到了错误
//        4. Print和BufferedOutputStream类一样,也带有缓冲区,两者区别在于后者只有缓冲区满的时候,才会自动执行物理写数据的操作,而前者可以让用户来决定缓冲区的行为,默认情况下printStream也只有在缓冲区满的时候,才会
//        自动执行物理写数据的操作,此外PrintStream的一个构造方法带有autoFlush参数,PrintStream(OutputStream out, boolean autoFlush)

//        如果autoFlush参数设为true,表示PrintStream在以下情况也会自动把缓冲区的数据写入到数据汇。1,输出一个字节数组,2,输出一个换行符,即执行print("\n")方法,

3,执行了println()方法

public class Test17 {

	public static void main(String[] args) throws IOException {
		// 1
		byte[] buff = new byte[]{2,15,67,-1,-9,9};
		ByteArrayInputStream in = new ByteArrayInputStream(buff,1,4);
		// 每读到一个字节类型的元素,都会转换为int类型,这里是通过二进制转换后得出的结果,和把byte类型转换为int类型,在赋值运算中的类型转换是两回事,在赋值中,把byte类型赋给int类型,取值不变
		int data = in.read();
		while(data != -1){
			System.out.println(data + "");
			data = in.read();
		}
		in.close();
		
		// 2
		final int SIZE = 1024;
		FileInputStream fi = new FileInputStream("D:\\test.txt");
		FileOutputStream fo = new FileOutputStream("D:\\out.txt");
		byte[] buff1 = new byte[SIZE];
		int len = fi.read(buff1);
		while(len != -1){
			fo.write(buff1,0,len);
			len = fi.read(buff1);
		}
		in.close();
		
		// 3
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		out.write("你好".getBytes("UTF-8")); // 把 "你好" 的UTF-8字符编码写到字节数组中
		
		byte[] buff2 = out.toByteArray(); // 获得字节数组
		out.close();
		
		ByteArrayInputStream ba = new ByteArrayInputStream(buff2);
		int len2 = ba.available();
		byte[] buffIn = new byte[len2];
		ba.read(buffIn); // 把buff字节数组中的数据读入到buffIn中
		ba.close();
		System.out.println(new String(buffIn,"UTF-8")); //由字符编码创建字符串
		
		// 4
		ByteArrayOutputStream out2 = new ByteArrayOutputStream();
		out2.write(259); // 执行这部时,write()方法只会向输出流写入一个字节,259是int类型,他的二进制形式是 00000001 00000011, write截取后面8位,因此write方法实际上向输出流写入的字节为3
		
		byte[] buff3 = out2.toByteArray(); // 获得字节数组
		out2.close();
		
		System.out.println("buff3.length=" + buff3.length);

		ByteArrayInputStream ba1 = new ByteArrayInputStream(buff3);
		int data3;
		while ((data3=ba1.read())!=-1) {
			System.out.println(data3);
		}
		ba1.close();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值