文件、管道、网络、字节 字符数组
文件
文件是一种常用的数据源或者存储数据的媒介。
读文件
写文件
随机存取文件
通过RandomAccessFile对文件进行随机存取。
RandomAccessFile可以覆盖一个文件的某些部分、或者追加内容到它的末尾、或者删除它的某些内容,当然它也可以从文件的任何位置开始读取文件。
管道
管道为运行在同一个JVM中的两个线程提供了通信的能力。所以管道也可以作为数据源以及目标媒介。
创建管道
一个PipedInputStream流应该和一个PipedOutputStream流相关联。
一个线程通过PipedOutputStream写入的数据可以被另一个线程通过相关联的PipedInputStream读取出来。
代码示例
public class PipedCreate {
public static void main(String[] args) throws IOException {
final PipedOutputStream pipedOut = new PipedOutputStream();
final PipedInputStream pipedIn = new PipedInputStream(pipedOut);
Thread t1 = new Thread(() -> {
try {
pipedOut.write("this is piped !".getBytes(StandardCharsets.UTF_8));
// 如果不关闭流 Write end dead
pipedOut.close();
} catch (IOException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
int data = pipedIn.read();
while (data != -1) {
System.out.print((char)data);
data = pipedIn.read();
}
pipedIn.close();
} catch (IOException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
}
java.io.IOException: Write end dead
java.io.IOException: Write end dead
at java.io.PipedInputStream.read(PipedInputStream.java:310)
at com.lingyiwin.io.PipedCreate.lambda$main$1(PipedCreate.java:30)
at java.lang.Thread.run(Thread.java:748)
原因上述示例t1线程输出管道未关闭造成的。
管道死锁
read()方法和write()方法调用时会导致流阻塞,在一个线程中同时进行读和写,可能会导致线程死锁。
网络
当两个进程之间建立了网络连接之后,他们通信的方式如同操作文件一样:利用InputStream读取数据,利用OutputStream写入数据。
- Java网络API用来在不同进程之间建立网络连接,
- Java IO则用来在建立了连接之后的进程之间交换数据。
字节流
ByteArrayInputStream示例
public class ByteArrayInput {
public static void main(String[] args) throws IOException {
String str = "lingYiWin";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
//将bytes装到输入流中
InputStream inputStream = new ByteArrayInputStream(bytes);
int data = inputStream.read();
while (data != -1) {
System.out.print((char) data);
data = inputStream.read();
}
inputStream.close();
}
}
ByteArrayOutputStream示例
public class ByteArrayOutput {
public static void main(String[] args) throws IOException {
String str = "this is byte Array output stream";
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
ByteArrayOutputStream output = new ByteArrayOutputStream();
//将字符写入字符流
output.write(bytes,0,str.length());
System.out.println(output);
}
}
System.in
//控制台输入
System.in.read();
InputStream此抽象类是表示字节输入流的所有类的超类。
InputStream read从输入流读取下一个数据字节。
public final static InputStream in = null;
System.in是一个典型的连接控制台程序和键盘输入的InputStream流。
System.out
System.out等于public final static PrintStream out = null;
System.out是一个PrintStream流。System.out一般会把你写到其中的数据输出到控制台上。
System.in
System.err是一个PrintStream流。System.err与System.out的运行方式类似。