IO流
Java的IO流是实现输入\输出的基础,它可以方便的实现数据的输入\输出的操作,在Java中把不同的输入\输出源(键盘、文件、网络连接等)抽象表述为“流”(stream),通过流的方式允许Java程序使用相同的方式来访问不同的输入\输出源。
分类
按照流向来分分为输入流和输出流
输入流:只能从中读取数据,而不能向其中写数据。
输出流:只能向其中写数据,而不能从中读取数据。
字节流和字符流
字节流和字符流操作方式几乎完全一样,区别只是操作的数据单元不同。
InputStream和Reader
InputStream和Reader是所有输入流的抽象基类,本身不能创建实例来进行输入。
InputStream里包含如下三个方法:
1.int read(): 从输入流中读取单个字节返回读取的字节数据。
2.int read(byte[] b):从输入流中读取b.length个字节数据,并将数据储存在字节数组b中,返回实际读取的字节数。
3.int read(byte[] b,int off,int len):从输入流中读取len个字节数据,并将其存储在数组b中,从off位置开始,返回实际读取的字节数。
Reader里包含如下几个方法
1.int read(): 从输入流中读取单个字符返回读取的字符数据。
2.int read(char[] cbuf):从输入流中读取cbuf.length个字符数据,并将数据储存在字符数组cbuf中,返回实际读取的字符数。
3.int read(char[] cbuf,int off,int len):从输入流中读取len个字符数据,并将其存储在数组b中,从off位置开始,返回实际读取的字符数。
从上面我们就可以看出 InputStream和Reader功能基本相同。那么我们如何判断读到流的末尾了呢?当方法返回-1时就说明到了末尾。
用FileInputStream读取自身
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args)throws IOException {
FileInputStream fileInputStream = new FileInputStream(
"FileInputStreamTest.java");
byte[] bytes = new byte[1024];
int len = 0;
while((len = fileInputStream.read(bytes)) != -1){
System.out.println(new String(bytes,0,len));
}
fileInputStream.close();
}
}
用FileReade读取自身:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderTest {
public static void main(String[] args)throws IOException {
FileReader fileReader = new FileReader(
new File("FileInputStreamTest.java"));
char[] chars = new char[8];
int len = 0;
while((len = fileReader.read(chars)) != -1){
System.out.println(new String(chars,0,len));
}
fileReader.close();
}
}
在InputStream和Reader还支持如下几个方法来记录移动指针位置。
1.void mark(int readAheadLimit):在记录指针当前位置记录一个标记(mark)
2.boolean markSupported():判断此输入流是否支持mark()操作即是否支持记录标记。
3.long skip(long n):记录指针向前移动n个字节/字符。
只是目前的FileInputStream和FileReade不支持mark操做。
OutputStream和Writer
OutPutStream和Writer也非常的相似。两个流都提供了如下三种方法;
1.void write(int c):将指定的字节/字符输出到输出流中,其中c既可以代表字符也可以代表字节
2.void write(byte [] /char [] buf):将字节/字符数组中的数据输出到指定的输出流中
3.void write(byte []/char [] buf,int off,int len):将字节数组/字符数组中从off开始,长度len的字节/字符输出到输出流中。
因为字符流以字符为基本操作单位,所以也可以直接用String代替字符数组。
1.void write(String str):将字符串中的数据输出到指定的输出流中
2.void write(String str,int off,int len):将字符数串中从off开始,长度len的字符串输出到输出流中。
有了输出流我们就可以复制文件了
public class CopyFile {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("CopyFile.java");
FileOutputStream out = new FileOutputStream("CopyFile.txt");
int len=0;
byte [] bytes = new byte[1024]
while ((len=in.read())!=-1){
out.write(bytes,0,len);
}
System.out.println("复制完成");
in.close();
out.close();
}
}
字节流可以操作任何类型的文件。但是字符流只能操作文本文件。如果希望输出字符串的内容,那么使用Write会更好一点。
public class IODemo {
public static void main(String[] args) throws IOException {
FileWriter fileWriter = new FileWriter("pome.txt");
fileWriter.write("年少不听李宗盛");
fileWriter.write("\r\n");
fileWriter.write("听懂已是不惑年");
fileWriter.write("\r\n");
fileWriter.write("初听不识曲中意");
fileWriter.write("\r\n");
fileWriter.write("再听已是曲中人");
fileWriter.write("\r\n");
fileWriter.close();
}
}
输入输出流体系
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
访问数组 | ByteArraylnputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BuferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
抽象基类 | FilterlnpurStream | FilterOutputStream | FilterReader | FilterWriter |
打印流 | Printtread | PrintWriter | ||
特殊流 | DataInputStream | DataOuputStream |
转换流
转InputStreamReader换流用于字节流和字符流的转换InputStreamReader将字节输入流转换成字符输入流
OutputStreamReader将字节输出流转换成字节输入流
public class KeyinTest{
public static void main(String[] args){
try(
//将Sytem.in对象转换成Reader对象
InputstreamReader reader = new InputstreamReader (System. in);//将普通的Reader包装成Buf feredReader
BufferedReader br = new Buf feredReader (reader))
{
String line = null;
//采用循环方式来逐行地读取
while ((line br.readLine()) != null)
//如果读取的字符串为"exit", 则程序退出if (line . equals("exit")){
System.exit(1);//打印读取的内容
System.out.printin("输入内容为:" + line);
}catch{(IOException ioe)
{
ioe .printstackTrace();
}
}
RandomAccessFile
这是一个support Mark的流他可以记录文件指针的位置,同时也可以设置当前文件读取开始的位置。
//读操作
RandomAccessFile rw = new RandomAccessFile("f.txt", "rw");
//你怎么写的就怎么读取
int i = rw.readInt();
long pointer = rw.getFilePointer();
System.out.println("指针位置"+pointer);
System.out.println(i);
boolean b = rw.readBoolean();
pointer = rw.getFilePointer();
System.out.println("指针位置" + pointer);
System.out.println(b);
byte b1 = rw.readByte();
pointer = rw.getFilePointer();
System.out.println("指针位置" + pointer);
System.out.println(b1);
String s = rw.readUTF();
System.out.println(s);
pointer = rw.getFilePointer();
System.out.println("指针位置" + pointer);
rw.seek(0);//定位指针的位置
int and= rw.readInt();
System.out.println(and);
rw.seek(6);
String s1 = rw.readUTF();
System.out.println(s1);
//写操作
rw.writeInt(100);
rw.writeBoolean(false);
rw.writeByte(10);
rw.writeUTF("你好");
rw.close();
}
PrintStream和PrintWriter
打印流的特点:
1 打印流只能操作目的地,不能操作数据源(不能进行读取数据);
2可以操作任意数据类型的数据 调用print() 方法可以写任意数据类型
3如果我们启用自动刷新,那么在调用println、printf 或 format 方法中的一个方法的时候,会完成自动刷新
方法:
public PrintWriter(OutputStream out, boolean autoFlush) 启动自动刷新
public PrintWriter(Writer out, boolean autoFlush) 启动自动刷新
PrintStream printStream = new PrintStream("b.txt");
printStream.println("abc");
printStream.print(3.14);
printStream.print(true);
printStream.println(3.14);
printStream.write("bbb".getBytes());
printStream.write("bbbb".getBytes());
printStream.close();
System.out.println("-----------------------------------");
//out 标准的输出流 关联的设备是屏幕
PrintStream out = System.out;
out.println("abc");
// System.out.println();
PrintWriter writer = new PrintWriter(new File("c.txt"));
writer.write("abc");
writer.write("aaa");
writer.flush();
writer.println("asfasdfasdf");
writer.flush();
writer.println("asfadfadfsa");
writer.flush();
writer.close();
当然还有很多的输入输出流,这里就不再一一赘述了。用法大多一样,只是操作的对象不相同。