Java se部分主要包括四大块内容:集合,io,多线程,网络编程。这篇文章主要是介绍IO部分。
1.流的概念
流是字节序列的抽象概念。
文件是数据的静态存储形式,而流是指数据传输时的形态。
流是:字节序列的抽象概念,数据传输的一种数据序列。提供了一种统一的方式向IO设备中读取和写入的方式。
文件是:一些具有永久存储,有序的具有名称的字节的集合。文件是流可操作的IO设备之一。除了文件流,还有内存流,网络流,磁带流……
流类分为两大类:节点流类和过滤流类(也叫处理流类)。 节点流:用于直接操作目标设备所对应的流类。节点流类所对应的IO源或目标称为流节点。比如我们用一个类和一个文件或网络相关联,那么这个类就叫做节点流类,这个文件或网络就叫做流的节点。
过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的,是在数据传输过程中起装饰和限制作用。
流可以分为字节流和字符流。字节流的根类是InpuStream和OutputStream,字符流的根类是Writer 和reader。这四个都是抽象类
接下来我们逐一介绍:
2.InputStream类
程序可以从中连续读取字节的对象叫输入流,在java中,用InputStream类来描述所有输入流的抽象基类。
int read() 如果读取结束返回-1,如果没有结束,但是暂时也没有数据可读,read方法将阻塞,直到有数据可读。
3.OutputStream类
此抽象类是表示输出字节流的所有类的抽象基类。输出流接受输出字节并将这些字节发 送到某个接收器。
void flush()方法:刻骨铭心的记忆: 刷新此输出流并强制写出所有缓冲的输出字节。
4.FileInputStream 与 FileOutputStream类
FileInputStream 和 FileOutputStream 类分别用来创建磁盘文件的输入流和输出流对象,按字节读取文件内容,通过他们的构造函数来指定文件路径和文件名。
创建FileOutputStream实例对象时,指定的文件应当是存在和可读的。
创建FileOutputStream实例对象时,可以指定不存在的文件名(如果指定的文件已经存在,这个文件的原来内容将被覆盖清除。如果不存在,将创建一个新的文件),但是不能指定一个 被其他程序打开了的文件。
思考题:要将A文件的内容写入B文件,在程序代码中,是用输出类对象,还是用输入类对象来连接A文件并完成对A文件的操作呢?
答:输入和输出的概念多是相对于程序而言的,并不是文件。我们要从A文件中读取信息写入程序中,所以应该用文件输入流FileInputStream。
例一 往指定文件中输出内容:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
File file=new File("c:/java/abc.txt");
OutputStream out=new FileOutputStream(file);
byte [] a="agaaergaggha".getBytes();
out.write(a);
out.close();
}
}
例二 从指定文件中读取文件:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
File file=new File("c:/java/abc.txt");
InputStream in=new FileInputStream(file);
byte []a= new byte[6];
int len=in.read(a);
while(len!=-1){
for(int i=0;i<a.length;i++)
System.out.println((char)a[i]);
len=in.read(a);
}
in.close();
}
}
例三 从某文件中读取数据复制到指定文件中:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
InputStream in=new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\set和list.txt"));
OutputStream ou =new FileOutputStream(new File("C:\\Users\\DELL\\Desktop\\新建文本文档.txt"));
byte [] a =new byte[6];
int len =in.read(a);
while(len!=-1){
ou.write(a);
len=in.read(a);
}
ou.close();
in.close();
}
}
5.Reader 与 Writer(FileReader和FileWriter)
a)以上都是处理字节的,需要字节与字符的转化——————
Reader 和 Writer是所有字符流的抽象基类,用于简化对字符的输入输出编程,即用于读写文本数据。
用Reader和Writer类就可以直接进行字符串读取,简化了字符串的输入输出编程。但他们都是抽象类,用他们的子类FileReader、FileWriter就可以直接使用。
b) 文本文件只是二进制文件的一种特例。
c) 如果一个文件只存储了字符我们就称作是文本文件。
d) FileReader的Writer方法内部没有调用Flush()(刷新)方法将缓存中的信息写入硬盘,需要调用close方法才能真正的写入到硬盘中。
6.PipedInputStream与PipedOutputStream类(管道流类)
a) PipedInputStream类与PipedOutputStream类用于在应用程序中创建管道通信。
b) PipedInputStream管道对象用来接收PipedOutputStream管道对象所输出的信息。
c) 实际编程中要建立两个管道,相互连接。
7.PipedWriter和PipedReader字符文本的管道通信
a) 使用管道流类,可以实现各个程序模块之间的高内聚低偶合的通信。
8.ByteArrayInputStream与ByteArrayOutputStream
a) 内存虚拟文件,内存映像文件,都是把内存中的数据缓存区虚拟成一个文件,原来应该写入到硬盘文件的内容,可以写入内存中。原来应该从硬盘文件中读取的内容,也可以从内存中读取。这样可以大大提高应用程序的性能和效率。
b) 要在内存中定义一个大的数据缓冲区,其实就是定义一个字节数组。
c) 在Java中定义了ByteArrayInputStream和ByteArrayOutputStream,用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能。
9. StringReader类和StringWriter类来以字符IO流的方式处理字符串
重视IO程序代码的复用性
a) Sytem.in连接到键盘,是InputStream类型的实例对象。System.out连接到显示器,是PrintStream类的实例对象。
b) 不管各种底层物理设备用什么方式实现数据的终止点,InputStream的read方法总是返回-1来表示输入流的结束。
c) 在Windows下,按下Ctrl+Z组合键可以产生键盘输入流的结束标记,在Linux下,则是按下Ctrl+D组合键来产生键盘输入流的结束标记。
例一 往指定文件中输出内容:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
Writer ou=new FileWriter(new File ("C:\\Users\\DELL\\Desktop\\新建文本文档.txt"));
char []a="asfaratgade".toCharArray();
ou.writer(a);
ou.close();
}
}
例二 从指定文件中读取文件:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
Reader in=new FileReader(new File("C:\\Users\\DELL\\Desktop\\set和list.txt"));
char []a=new char[6];
int len=in.read(a);
while(len!=-1){
System.out.println(a);
len=in.read(a);
}
in.close();
}
}
例三 从某文件中读取内容复制到指定文件中:
import java.io.*;
public class Test{
public static void main(String[]args)throws IOException{
Reader in=new FileReader(new File("C:\\Users\\DELL\\Desktop\\set和list.txt"));
Writer ou=new FileWriter(new File("C:\\Users\\DELL\\Desktop\\新建文本文档.txt"));
char []a=new char[30];
int len=in.read(a);
while(len!=-1){
ou.write(a);
len=in.read(a);
}
ou.close();
in.close();
}
}
例四 ByteArrayInputStream
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class ByteArrayInputStreamTest1 {
public static void main(String[] args) throws IOException {
String temp = "abc";
byte[] b = temp.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(b);
for (int i = 0; i < 2; i++) {
int c;
while (-1 != (c = in.read(b))) {
if (0 == i) {
for (int d = 0; d < b.length; d++) {
System.out.println((char) b[d]);
}
} else {
for (int d = 0; d < b.length; d++) {
System.out.println(Character.toUpperCase((char) b[d]));
}
}
}
System.out.println();
in.reset();
}
}
}
例五 ByteArrayOutputStream:
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class ByteArrayOutputStreamTest1
{
public static void main(String[] args) throws Exception
{
ByteArrayOutputStream f = new ByteArrayOutputStream();
String str = "hello world welcome";
byte[] buffer = str.getBytes();
f.write(buffer);
byte[] result = f.toByteArray();
for(int i = 0; i < result.length; i++)
{
System.out.print((char)result[i] +" ");
}
OutputStream os = new FileOutputStream("test.txt");
f.writeTo(os);
f.close();
os.close();
}
}
例六 自定义流:
import java.io.IOException;
import java.io.InputStream;
public class MyOwnStream1 {
public static void main(String[] args) throws Exception {
byte[] b = new byte[16];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) i;
}
MyByteArrayInputStream mbais = new MyByteArrayInputStream(b);
while (true) {
int c = mbais.read();
if (c < 0) {
break;
}
System.out.print(c + " ");
}
System.out.println();
}
}
class MyByteArrayInputStream extends InputStream {
protected byte[] data;
protected int ptr = 0;
public MyByteArrayInputStream(byte[] b) {
this.data = b;
}
@Override
public int read() throws IOException {
return (ptr < data.length) ? (data[ptr++]) : -1;
}
}
例七 打印流:
import java.io.*;
import java.util.*;
public class Test{
public static void main(String []args)throws IOException{
PrintStream p=System.out;
p.println(12);
p.println(24.23);
p.println(true);
p.println('A');
p.println("我爱你中国");
p.println(new Student ("张三 ",34,2424151));
p.close();
test2();
}
public static void test2()throws IOException{
FileOutputStream out =new FileOutputStream(new File("C:\\Users\\DELL\\Desktop\\课外作业.txt"));
PrintStream ps=new PrintStream(out);
ps.println(12);
ps.println(34.5);
ps.println(true);
ps.println('A');
ps.println("我爱你中国");
ps.println(new Date());
ps.println(new Student("李四",45,736546));
ps.close();
}
}
class Student{
private String name ;
private int age ;
private int id;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", id=" + id + "]";
}
public Student(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
例八 通过键盘录入,利用打印流 和转换流,往指定文件中输出信息:
import java.io.*;
public class Test{
public static void main(String []args)throws IOException{
BufferedReader bre =new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw=new PrintWriter(new FileWriter(new File ("C:\\Users\\DELL\\Desktop\\课外作业.txt")));
String data = bre.readLine();
while(data!=null){
pw.write(data);
pw.flush();
data=bre.readLine();
pw.close();
bre.close();
}}}
例九 数据输出输入流:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class DataStream1
{
public static void main(String[] args) throws Exception
{
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream("data.txt")));
byte b = 3;
int i = 12;
char ch = 'a';
float f = 3.3f;
dos.writeByte(b);
dos.writeInt(i);
dos.writeChar(ch);
dos.writeFloat(f);
dos.close();
DataInputStream dis = new DataInputStream(new BufferedInputStream(
new FileInputStream("data.txt")));
System.out.println(dis.readByte());
System.out.println(dis.readInt());
System.out.println(dis.readChar());
System.out.println(dis.readFloat());
dis.close();
}
}
例十 字符数组输入流:
import java.io.CharArrayReader;
public class CharArrayReader1 {
public static void main(String[] args) throws Exception {
String tmp = "abcdefg";
char[] ch = new char[tmp.length()];
tmp.getChars(0, tmp.length(), ch, 0);
CharArrayReader input = new CharArrayReader(ch);
int i;
while (-1 != (i = input.read())) {
System.out.println((char) i);
}
}
}
例十一 转换流:
public static void main(String[] args) throws IOException {
//字节流-->字符流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new FileWriter("is2.txt"));
String line = null;
while((line = br.readLine())!=null){
if("over".equals(line)){
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
最后再说一下 序列化和反序列化:
所谓的序列化:就是把对象保存在文件里
反序列化:就是把文件里的数据的读取出来形成对象
作用是 :
永久的保存数据,使其持久化
可以在网络之间传输数据
举个例子:
package com.qianfeng.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// write();
read();
}
public static void write() throws IOException, IOException {
ObjectOutputStream outputStream = new ObjectOutputStream(
new FileOutputStream(new File("C:\\Users\\DELL\\Desktop\\测试.txt")));
Student student = new Student(20, "张三", 79868589);
outputStream.writeObject(student);
outputStream.close();
System.out.println("测试成功");
}
public static void read() throws IOException, IOException, ClassNotFoundException {
ObjectInputStream inputStream = new ObjectInputStream(
new FileInputStream(new File("C:\\Users\\DELL\\Desktop\\测试.txt")));
Student student2 = (Student) inputStream.readObject();
System.out.println(student2);
}
}
class Student implements Serializable {
private int age;
private String name;
private int id;
public Student() {
}
public Student(int age, String name, int id) {
super();
this.age = age;
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + ", id=" + id + "]";
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}