java并发系列之IO流

1、概述

1、输入和输出
	输入流可以理解为向内存输入,输出流可以理解为从内存输出
2、典型的数据源(数据媒介)
	文件
	管道
	网络连接
	内存缓存
	System.in, System.out, System.error
	
3、并发IO要注意的问题:
	在同一时刻不能有多个线程同时从InputStream或者Reader中读取数据,也不能同时往OutputStream或者Writer里写数据。
	你没有办法保证每个线程读取多少数据,以及多个线程写数据时的顺序
	
4、字节流
	字节数组:
	ByteArrayInputStream ByteArrayOutputStream
	缓存:
	new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"), 8 * 1024);
	new BufferedOutputStream(new FileInputStream("c:\\data\\input-file.txt"), 8 * 1024);
	data:
	new DataInputStream(new FileInputStream("binary.data"));
	new DataOutputStream(new FileInputStream("binary.data"));
	
5、FileReader(FileWriter)不能指定编码
       用InputStreamReader配合FileInputStream来替代FileReader
       
6、字符缓存流
	BufferedReader reader = new BufferedReader(new FileReader("c:\\data\\input-file.txt"), 8 * 1024);
	reader.readLine()
	BufferedWriter writer = new BufferedWriter(new FileWriter("c:\\data\\output-file.txt"), 8 * 1024);
	
7、另外有PipedReader、PipedWriter、CharArrayReader、CharArrayWriter与字节流相对应
8、其他字节流
  PrintStream:System.out和System.err是PrintStream类型的变量
      其他字符流
  PrintWriter,StringReader,StringWriter

 

2、InputStreamReader和OutputStreamWriter

package io.character;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public class InputStreamReaderDemo {

	public static void main(String[] args) throws IOException {
		//读取
		Reader reader = 
				new InputStreamReader(new FileInputStream("E:/nomanager/test/data.txt"),"UTF-8");
		
		char[] c=new char[1024];
		int len=0;
		while((len=reader.read(c))!=-1){
			System.err.println(new String(c,0,len));
		}
		reader.close();
		
		//写入
		
		Writer writer = 
				new OutputStreamWriter(new FileOutputStream("E:/nomanager/test/data.txt",true),"UTF-8");
		
		writer.write("Hello World");
		
		writer.close();

		BufferedReader bufferedReader = new BufferedReader(new FileReader(""));
		
		
		
	}
}

3、对象序列化与ObjectOutputStream、ObjectInputStream

package io.stream.object;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ObjectDemo {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//写对象
		ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("E:/nomanager/test/user.data"));
		
		User user = new User();
		user.setUserId(101);
		user.setUsername("李四");
		user.setBirthday(new Date());
		List course = new ArrayList();
		course.add("语文");
		course.add("数学");
		course.add("英语");
		course.add("物理");
		course.add("化学");
		course.add("生物");
		user.setCourse(course);
		output.writeObject(user);
		output.close();
		
		
		
		//读对象
		
		ObjectInputStream input = new ObjectInputStream(new FileInputStream("E:/nomanager/test/user.data"));
		User u = (User) input.readObject();
		System.err.println(u);
		input.close();

		
		
		
		
		

	}
}
package io.stream.object;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private int userId;
	private String username;
	private Date Birthday;
	private List course;
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Date getBirthday() {
		return Birthday;
	}
	public void setBirthday(Date birthday) {
		Birthday = birthday;
	}
	public List getCourse() {
		return course;
	}
	public void setCourse(List course) {
		this.course = course;
	}
	@Override
	public String toString() {
		return "User [userId=" + userId + ", username=" + username + ", Birthday=" + Birthday + ", course=" + course
				+ "]";
	}
	
	
}

 4、PipedInputStream和PipedOutputStream

package io.stream.pipe;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeDemo {

	
	public static void main(String[] args) {
		
		/*
		 * 1、Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力
		 * 2、当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,
		 *    这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁
		 */
		
		
		PipedInputStream pin = new PipedInputStream();
		PipedOutputStream pout = new PipedOutputStream();
		try {
			pin.connect(pout);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					pout.write("hello".getBytes());
					pout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}).start();
		
		
		
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				String s="";
				
				
				byte[] b=new byte[1024];
				int len=0;
				try {
					while((len=pin.read(b))!=-1){
						s+=new String(b,0,len);
					}
					
					pin.close();
					System.err.println(s.length());
					System.err.println(s);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}).start();
		
		
		
		
	}
}

5、RandomAccessFile

package io.stream;

import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

	
	public static void main(String[] args) throws IOException {
		//RandomAccessFile允许你来回读写文件,也可以替换文件中的某些部分。FileInputStream和FileOutputStream没有这样的功能
		//rw表示以读写方式打开文件
		RandomAccessFile file = new RandomAccessFile("E:/nomanager/test/data.txt", "rw");
		//指向某个位置
		file.seek(1);
		//获取指针
		long pointer = file.getFilePointer();
		System.err.println(pointer);
		
		//读取RandomAccessFile
		byte[] b=new byte[1024];
		int len=0;
		while((len=file.read(b))!=-1){
			System.err.println(new String(b,0,len));
		}
		
		//写RandomAccessFile,如果不是从文件末尾写,写文件时会取代后面的字节
		System.err.println(file.getFilePointer());
		file.seek(0);
		file.write("ABCD".getBytes());
		
		
		file.close();

	}
}

6、异常处理Try With Resource

package io.stream;

import java.io.FileInputStream;
import java.io.IOException;

public class TryWithResourceDemo {

	
	public static void main(String[] args) {
		
		

		/*
		 * 1、当一个外部资源的句柄对象实现了AutoCloseable接口,JDK7中便可以利用try-with-resource语法更优雅的关闭资源,消除板式代码。
		 * 
		 * 2、try-with-resource时,如果对外部资源的处理和对外部资源的关闭均遭遇了异常,“关闭异常”将被抑制,“处理异常”将被抛出,但“关闭异常”并没有丢失,
		 * 	    而是存放在“处理异常”的被抑制的异常列表中。
		*/
		try(FileInputStream in = new FileInputStream("E:/nomanager/test/data.txt")) {
			byte[] b = new byte[1024];
			int len = 0;
			while((len=in.read(b))!=-1){
				System.err.println(new String(b,0,len));
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
}

7、克隆输入流

/**
     * 克隆InputStream对象,源输入流clone后已close,克隆出来的输入流使用完后要自己close
        * @Title: cloneInputStream
        * @param source 输入流源
        * @param count 克隆次数
        * @return List 克隆出来的输入流集合
     */
    public static List cloneInputStream(InputStream source,int count){
    	//将InputStream存于ByteArrayOutputStream中,复制InputStream
		ByteArrayOutputStream bout = new ByteArrayOutputStream();  
		byte[] buffer = new byte[1024];  
		int len = 0;  
		try {
			while ((len = source.read(buffer)) > -1 ) {  
				bout.write(buffer, 0, len);  
			}
			bout.flush();
		} catch (IOException e) {
			LogUtil.error("IO读写异常",e);
		} finally {
			try {
				if(null != source){
					source.close();
				}
			} catch (IOException e) {
				LogUtil.error("关闭IO流失败",e);
			}
		}
		
		List list = new ArrayList();
		for (int i=0;i

 

你可能感兴趣的:(java并发系列,并发,io)