IO流
JAVA流式输入输出原理:可以想象成一根管道怼到文件上,另一端是我们程序,然后流的输入输出都是按照程序本身作为第一人称说明的。比如 input,对于我们程序来说就是有数据输入我们程序,output就是我们程序输出数据到文件等。对象不能搞错了,否则就南辕北辙了。
输入流和输出流
节点流和处理流
节点流可以简单的理解为:一根管道直接怼到文件上,进行数据的读写。
处理流可以简单的理解为:套在节点流管道的管子,可以对流过节点流的数据进行处理,过滤等操作。
InputStream 抽象类
FileInputStream
PipedInputStream
FilterInputStream
ByteArrayInputStream
SequenceInputStream
StringBufferInputStream
ObjectInputStream
OutputStream 抽象类
FileOutputStream
PipedOutputStream
FilterOutputStream
ByteArrayOutputStream
ObjectOutputStream
Reader
BufferedReader
CharArrayReader
InputStreamReader
FilterReader
PipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
OutputStreamWriter
FilterWriter
PipedWriter
StringWriter
节点流类型
类型 字节流 字符流 File(文件) FileInputStream / FileOutputStream FileReader / FileWriter Memory Array ByteArrayInputStream / ByteArrayOutputStream CharArrayReader / CharArrayWriter Memory String -- StringReader / StringWriter Pipe(管道) PipedInputStream / PipedOutputStream PipedReader / PipedWriter
举例1:FileInputStream
import java.io.*;
public class Test {
public static void main(String[] args) {
int b = 0;
long num = 0;
FileInputStream ln = null;
try {
ln = new FileInputStream("I:/Java/Demo/test.txt");
} catch (FileNotFoundException e) {
System.out.println("文件不存在!");
System.exit(-1);
}
try {
while ((b=ln.read()) != -1) {
System.out.print((char)b);
num++;
}
ln.close();
System.out.println();
System.out.println("共读出:" + num + "个字节。");
} catch (IOException e) {
System.out.println("文件读取失败!");
System.exit(-1);
}
}
}
举例2:FileOutputStream
import java.io.*;
public class Test {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("I:/Java/Demo/test.txt");
out = new FileOutputStream("I:/Java/Demo/newtest.txt");
while((b=in.read()) != -1) {
out.write(b);
}
} catch (FileNotFoundException e) {
System.out.println("文件不存在!");
System.exit(-1);
} catch (IOException e) {
System.out.println("文件复制失败!");
System.exit(-2);
}
System.out.println("文件复制成功!");
}
}
处理流类型
处理类型 字节流 字符流 Buffering BufferedInputStream/BufferedOutputStream BufferedReader/BufferedWriter Filtering FilterInputStream/FilterOutputStream FilterReader/FilterWriter Converting between bytes and character -- InputStreamReader/OutputStreamWriter Object Serialization ObjectInputStream/ObjectOutputStream -- Data conversion DataInputStream/DataOutputStream -- Counting LineNumberInputStream LineNumberReader Peeking ahead PushbackInputStream PushbackReader Printing PrintStream PrintWriter
举例1:
import java.io.*;
public class Test {
public static void main(String[] args) {
int b = 0;
FileInputStream in = null;
BufferedInputStream bin = null;
try {
in = new FileInputStream("I:/Java/Demo/test.txt");
bin = new BufferedInputStream(in);
bin.mark(100);
for(int i=0; (i<=10)&&(b=bin.read()) != -1; i++) {
System.out.print((char)b);
}
bin.reset();
System.out.println();
for(int i=0; (i<=10)&&(b=bin.read()) != -1; i++) {
System.out.print((char)b);
}
} catch (FileNotFoundException e) {
System.out.println("文件不存在!");
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
举例2:
import java.io.*;
public class Test {
public static void main(String[] args) {
String s = null;
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("I:/Java/Demo/test.txt"));
BufferedReader br = new BufferedReader(new FileReader("I:/Java/Demo/test.txt"));
for(int i=0; i<100; i++) {
s = Double.toString(Math.random());
bw.write(s);
bw.newLine();
}
bw.flush();
while((s=br.readLine()) != null) {
System.out.println(s);
}
bw.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//0.7365309652822098
//0.577186775602007
//0.11736466966949166
//0.2998096440959087
//0.23859539950503672
//...
举例1:
import java.io.*;
public class Test {
public static void main(String[] args) {
try {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("I:/Java/Demo/test.txt"));
osw.write("1234567890");
System.out.println(osw.getEncoding());
osw.flush();
osw.close();
osw = new OutputStreamWriter(new FileOutputStream("I:/Java/Demo/test.txt", true), "ISO8859_1");
osw.write("abcdefghijklmn");
System.out.println(osw.getEncoding());
osw.flush();
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
举例2:
import java.io.*;
public class Test {
public static void main(String[] args) {
try {
String s = null;
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
while((s = br.readLine()) != null) {
if(s.equalsIgnoreCase("exit")) {
break;
}
System.out.println(s);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据流的作用?
比如,我们如何存储一个很大的数到文件?我们之前的方法是将其转换成字符串存储,可不可以直接存储呢?数据流可以。它提供了很多方法用于存储基础数据类型的数据,参看 API 文档。
举例1:
import java.io.*;
public class Test {
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 在内存自动生成一个 Byte[] 数组
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeDouble(Math.random());
dos.writeBoolean(true);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
dos.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
问题:我们写一个 double,写一个boolean写到哪里了呢?
其实,在我们 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 的时候,就在内存中开辟了一块空间,用来将程序要写入的数据写到这片内存中。
还有,在读数据的时候,由于这片内存的分配是按照队列的方式分配的,所以先写进去的数据要先读出来,如果如上面程序那样,先读boolean的话,就会读取到double 8个字节的第一个字节上,切记!
举例1:
import java.io.*;
public class Test {
public static void main(String[] args) {
PrintStream ps = null;
try {
FileOutputStream fos = new FileOutputStream("I:\\Java\\Demo\\test.txt");
ps = new PrintStream(fos);
if(null != ps) {
System.setOut(ps);
}
for(int i=0; i<60000; i++) {
System.out.print((char)i + " ");
if(i%50 == 0) {
System.out.println();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
将输出打印语句重定向到 test.txt 文件中。
举例2:
import java.io.*;
public class Test {
public static void main(String[] args) {
String filename = args[0];
if (filename != null) {
list(filename, System.out);
}
}
public static void list(String f, PrintStream fs) {
try {
String s = null;
BufferedReader br = new BufferedReader(new FileReader(f));
while ((s = br.readLine()) != null) {
fs.println(s);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
将 args[0] 所写的文件名对应的文件打印到终端。
举例3:
import java.io.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
String s = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
FileWriter fw = new FileWriter("I:/Java/Demo/log.txt", true);
PrintWriter log = new PrintWriter(fw);
while((s=br.readLine()) != null) {
if(s.equalsIgnoreCase("exit")) {
break;
}
System.out.println(s);
log.println("------");
log.println(s);
log.flush(); // 可以省略
}
log.println("--- " + new Date() + " ---");
log.flush(); // 可以省略
log.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
将从终端输入的内容作为 log 写到 log.txt 文件里面。
Object 流的作用:当我们存储一个元素的时候,(比如在画图软件上画了一个圆)我们的圆有很多属性,原点位置,半径大小,颜色,粗细等,既然每一个属性都需要存储,而且这些属性都在一个 Object 对象里面,那么我们为什么不直接写整个 Object呢?(这叫序列化。)
注意:当你 new 一个 Object 的时候,不单单只有你的属性,还有一些比如 Object的版本号,this,super 等。
举例:
import java.io.*;
public class Test {
public static void main(String[] args) {
TmpClass tm = new TmpClass();
tm.a =10;
tm.d = false;
try {
FileOutputStream fos = new FileOutputStream("I:/Java/Demo/text.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(tm);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("I:/Java/Demo/text.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
TmpClass t = (TmpClass) ois.readObject();
System.out.println(t.a + " " + t.b + " " + t.c + " " + t.d);
} catch (ClassNotFoundException c) {
System.out.println("读取文件失败");
} catch (IOException e) {
e.printStackTrace();
}
}
}
class TmpClass implements Serializable {
int a = 1;
int b = 2;
double c = 3.0;
boolean d = true;
}
总结