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
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(""));
}
}
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
+ "]";
}
}
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();
}
}
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();
}
}
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();
}
}
}
/**
* 克隆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