zoukankan      html  css  js  c++  java
  • JAVA学习第五十七课 — IO流(十一)

    一、管道流

    PipedInputStream 和 PipedOutPutStream

    输入和输出能够直接进行连接。结合线程使用

    管道流,顾名思义,写一个读一个。连成一个管子

    API文档:管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的全部数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其它线程将其写入到对应的 PipedOutputStream

    不建议对这两个对象尝试使用单个线程。由于这样可能死锁线程。

    管道输入流包括一个缓冲区。可在缓冲区限定的范围内将读操作和写操作分离开。

    假设向连接管道输出流提供数据字节的线程不再存在。则觉得该管道已损坏

    class Input implements Runnable{
    
    	private PipedInputStream pis;
    	Input(PipedInputStream pis){
    		this.pis = pis;
    	}
    	@Override
    	public void run() {
    		try {
    			byte[] by = new byte[1024];
    			int len = pis.read(by);
    			String str = new String(by,0,len);
    			System.out.println("str = "+str);
    			pis.close();
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    }
    class Output implements Runnable{
    	
    	private PipedOutputStream pos;
    	 Output(PipedOutputStream pos) {
    		// TODO Auto-generated constructor stub
    		this.pos = pos;
    	}
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		try {
    			Thread.sleep(5000);
    			pos.write("你好".getBytes());//字符串转字节流
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    		
    	}
    }
    public class Main {
    
    	public static void main(String[] args)throws IOException{
    		PipedInputStream pis = new PipedInputStream();
    		PipedOutputStream pos = new PipedOutputStream();
    		pis.connect(pos);//两流对接
    		
    		Thread t1 = new Thread(new Input(pis));
    		Thread t2 = new Thread(new Output(pos));
    		t1.start();
    		t2.start();
    	}
    }

    管道流应用不是非常多,可是其自身非常有特点

    IO包中的其它类

    操作基本类型数据的流对象—DataInputStream与DataOutputStream

    操作字节数组—ByteArrayInputStream与ByteArrayOutputStream

    操作字符数组—CharArrayInputStream与CharArrayOutoutStream

    操作字符串—StringWriter与StringReader


    DataInputStream与DataOutputStream

    public static void read() throws IOException {
    		// TODO Auto-generated method stub
    		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
    		String str = dis.readUTF();
    		System.out.println(str);
    		dis.close();
    	}
    
    	public static void DataStreamDemo() throws IOException {
    		// TODO Auto-generated method stub
    		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
    		dos.writeUTF("你好胖");以与机器无关方式使用 <a target=_blank href="">UTF-8 改动版</a>编码将一个字符串写入基础输出流。
    		dos.close();
    	}
    剩下的方法和OutputStream、InputStream差点儿相同


    操作数组的流


    源和汇都是内存。ByteArrayInputStream、ByteArrayOutputStream

    ByteArrayOutputStream:此类实现了一个输出流,当中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自己主动增长。可使用 toByteArray()toString() 获取数据,关闭 ByteArrayOutputStream 无效。

    	public static void ByteStreamDemo() throws IOException {
    		ByteArrayInputStream bis = new ByteArrayInputStream("asdfd".getBytes());
    		ByteArrayOutputStream bos = new ByteArrayOutputStream();
    		int len = 0;
    		while((len = bis.read())!=-1){
    			bos.write(len);
    		}
    		System.out.println(bos.toString());
    	}

    剩下的流使用方法和ByteArrayInputStream都是同样的

    编码问题

    编码问题无非就是文字和二进制之间的相互转换

    字符串->字符数组:编码

    字符数组->字符串:解码

    public static void Demo() {
    		String str = "你好";
    		//编码
    		byte[] by = str.getBytes();
    		for(byte b : by){
    			System.out.println(b);
    		}
    		
    		//解码
    		String str1 = new String(by);// == new String(by,"GBK");
    		System.out.println(str1);
    	}

    编码编对了,有可能能成功解码

    练习:依照最长字节数截取字符串
    在java中字符串“abcd”与“ab你好”长度一样,都是4个字符,可是字节数不一样
    定义方法,依照最大的字节数来取字节
    如:“ab你好”为例。假设依照3个字节来取文字。取“ab”和半个你,半个舍弃,4个字节取“ab你”,5个字节还是“ab你”
    	public static void main(String[] args)throws IOException{
    	
    		String str = "ab你好asdas撒旦发射的";
    		int len = str.getBytes("GBK").length;
    		for(int i = 0;i<len;i++){//依照i个字节取
    			System.out.println("OK : "+Demo(str,i+1));
    		}
    	}
    
    	public static String Demo(String str,int len) throws IOException {
    		byte[] by = str.getBytes("GBK");
    		int count = 0;//记录从哪个索引開始,字节不是汉字
    		for(int i = len-1;i>=0;i-- ){
    			if(by[i]<0){
    				count++;
    			}else {
    				break;
    			}
    		}
    	//汉字相应2个字节,汉字的个数 = 有负字节数/2
    	return (count & 1) == 0?new String(by,0,len):new String(by,0,len-1);
    		
    	}




  • 相关阅读:
    C# 监测每个方法的执行次数和占用时间(测试1)
    C# 依赖注入那些事儿
    SQL Server GROUP BY 后 拼接 字符串
    C# 根据Excel生成树
    C# 反射赋值
    C# 集合转换为DataTable
    Oracle 未能加载文件或程序集Oracle.DataAccess
    MySQL 各种主流 SQLServer 迁移到 MySQL 工具对比
    平衡树
    数据结构优化dp
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/5068853.html
Copyright © 2011-2022 走看看