1、流都在java.io包中
FileReader类中的方法
len=fr.read(buf)返回值是实际写入数组的字节个数,buf字节数组名字,数组的大小大于len.
(1)把当前程序与另外设备进行连接数据的传输的管道(流),这种类为流。管道上有不同的按钮实现不同的功能。
import java.io.*;
public class TestFileReader {
public static void main(String[] args)throws Exception
{
// TODO Auto-generated method stub
FileReader fr=new FileReader("D://javaTest//TestFileReader.java");//管道fr流建立。
int ch=fr.read();
while(-1!=ch){
System.out.printf("%c",(char)ch);
ch=fr.read();
}
fr.close();
}
}
fr叫做流。
流的分类和使用
流的分类:按照数据流方法不同分为输入流和输出流;按照数据单位不同分类字节流和字符流;按照功能不同分为(字节流)原始流和(处理流)包裹流。
(1)四大基本抽象流 InputStream OutputStream Reader Writer(字符流占用两个字节)
InputStream 基本方法:len= fis.read(buff);从文件中读取数据,放入buff数组,len为在存放在数组中实际字节个数。
OutputStream 基本方法: fos.write(buf)是指,将buf中数据输出写到fos文件中。
字节流和字符流区别:一个是字节操作,一个是字符操作(占用两个字节),对文本操作需要使用字符流。
字符流中利用缓冲区,字节流可以处理各种设备信息,图片,音乐等等。但是文本文件可以用字节流进行拷贝。两个文件之间的数据传输。对于本身不是字符编码的,若使用字符流,将二进制数据解读为字符,字符的二进制代码写入,将会出错。
(2)文件流
FileInputStream ,利用其构造函数实现将输入流连接到某个文件的功能。
FileOutputStream,同理
处理流类型常见的有
(3)缓冲流:带有缓冲区的流,减少我们对IO范文次数,保护硬盘。为处理流,必须依赖节点流。
四种构造方法,BufferInputStream,BufferoutputStream, BufferReader, BufferWriter.
带缓冲区的字符流读取文本文件,可以一行一行读取。不需要一个字节读。
import java.io.*;
import java.util.*;
public class TestBufferInputStreamOutputStreamCopy {
public static void main(String[] args) {
// TODO Auto-generated method stub
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try
{
bos=new BufferedOutputStream(new FileOutputStream("D:/javaTest/TestA.txt"));
bis=new BufferedInputStream(new FileInputStream("D:/javaTest/妹妹来看我.mp3"));
byte[] buf = new byte[1024];
int len=bis.read(buf,0,1024);
//一定要注意,这不是从buf中读数据,而是从bis所关联到的D:\\综艺\\电影\\猫和老鼠\\CD4.rmvb文件中读取数据,
//并将读取的数据写入bis自己的默认缓冲区中,然后再将缓冲区的内容写入buf数组中,每次最多向buf数组中写入1024个字节,
//返回实际写入buf数组的字节个数,如果读到了文件的末尾,无法再向buf数组中写入数据,则返回-1
while(-1!=len)
{
bos.write(buf, 0, len);// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。
len = bis.read(buf); //等价于 bis.read(buf, 0, buf.length);
}
bos.flush();
bis.close();
bos.close();
}
catch(FileNotFoundException e) {
System.out.println("没有找到文件");
System.exit(-1);
}
catch(IOException e) {
System.out.println("文件读写错误");
System.exit(-1);
}
System.out.println("文件复制成功");
}
}
(4)转换流
OutputStreamWriter,InputStreamReader
例子:将键盘输入的字符组成字符串直接赋值给String对象
import java.io.*;
public class TestStringInput {
public static void main(String[] args) {
String str=null;
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
try {
str=br.readLine();//直接回车,函数返回的是“”空字符。而不是null
}
catch(IOException e) {
e.printStackTrace();
System.exit(-1);
}
System.out.println(str);
try
{
br.close(); //会抛出IOException异常
}
catch (IOException e)
{
e.printStackTrace();
System.exit(-1);
}
}
}
(5)数据流:DataInputStream直接从底层字节输入流读取java基本类型的数据和String类型数据。常用方法:
DataOutputStream(包裹流必须依附于OutputStream)能够以一种机器无关的方式,直接将java基本类型和String类型数据写出到其他字节输出流。(将基本类型数据写到其他的字节输出流)
例如:实现将long类型的数据写入byte数组,再从byte数组中把该数据读取出来。
分析:将基本类型写入字节数组,用到writeLong(),再将其读取利用readLong(),其中利用到ByteArrayOutputStream和ByteArrayIntputStream
import java.io.*;
public class TestDataInputStreamOutputStream {
public static void main(String[] args) {
// TODO Auto-generated method stub
//DataOutputStream必须依附于字节流,先创建字节流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(bos);
long n=1234;
try {
dos.writeLong(n);
}
catch(Exception e) {
}
byte[] buf2=bos.toByteArray();
ByteArrayInputStream bis=new ByteArrayInputStream(buf2);
DataInputStream dis=new DataInputStream(bis);
long m;
try {
m=dis.readLong();
System.out.printf("%d", m);
}
catch(Exception e) {
}
}
}
1234
(4)转换流:
OutputStreamWriter:将OutputStream流转换为Writer流。
InputStreamReader:将InputStream流转换为Reader流。
两者均为包裹流
例:实现将键盘输入的字符组成字符串直接赋值给String对象。
import java.io.*;
public class TestStringInput {
public static void main(String[] args) {
String str=null;
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
try {
str=br.readLine();
}
catch(IOException e) {
e.printStackTrace();
System.exit(-1);
}
System.out.println(str);
try
{
br.close(); //会抛出IOException异常
}
catch (IOException e)
{
e.printStackTrace();
System.exit(-1);
}
}
}
(6)print流:只输出不输入。
(Writer,OutputStream基本流,DataOu)
PrintWriter输出字符
PrintStream输出字节
标准输入输出的重定向
例:实现将键盘输入的数据输入到文件A中,若输入有误,则把出错信息输出到B文件。
import java.io.*;
import java.util.*;
/*
* 从键盘输入的数据放入A文件,若按要求输入的数据为整数,
* 则输入数据不是整数则将出错信息放入另一个文件。
* */
public class TestSetSystemOut {
public static void main(String[] args) {
// TODO Auto-generated method stub
PrintStream psOut=null;
PrintStream psError=null;
Scanner sc=null;
try {
psOut=new PrintStream("D:/javaTest/TestA.txt");
psError=new PrintStream("D:/javaTest/TestError.txt");
sc=new Scanner(System.in);
int num;
System.setOut(psOut);
System.setErr(psError);
while(true) {
num=sc.nextInt();
System.out.println(num);
}
}
catch(Exception e) {
System.err.println("出错是:");
e.printStackTrace();
}
}
}
(7)对象输入流输出流(ObjectInputStream和ObjectOutputStream)object流
对象的序列化:把一个Object对象直接转化为字节流,然后把这个字节流直接写入本地硬盘或网络中。若要想把某个对象序列化,必须实现Serializable接口。标志作用,里面没有任何方法。
import java.io.*;
/*
* 将创建的类对象内容先写入一个文件中,然后读取文件中的内容,并在显示器中输出对象
*
* */
public class TestObjectIO
{
public static void main(String[] args)
{
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Student ss = new Student("zhansan", 1000, 88.8f); //注意88.8f不能改为88.8
Student ss2 = null;
try
{
FileOutputStream fos = new FileOutputStream("D:/javaTest/ObjectOut.txt");
oos = new ObjectOutputStream(fos);//包裹流,依附于文件字节流
oos.writeObject(ss);
ois = new ObjectInputStream(new FileInputStream("D:/javaTest/ObjectOut.txt"));
ss2 = (Student)ois.readObject(); //(Student)不能省 ois.readObject();如果ois中的某个成员是transient,则该成员是不会被读取的,因为该成员不会被保存,何来读取之说?!
System.out.println("ss2.sname = " + ss2.sname);
System.out.println("ss2.sid = " + ss2.sid);
System.out.println("ss2.sscore = " + ss2.sscore);
}
catch (FileNotFoundException e)
{
System.out.println("文件没有找到!");
System.exit(-1);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(-1);
}
finally
{
try
{
oos.close();
ois.close();
}
catch (Exception e)
{
e.printStackTrace();
System.exit(-1);
}
}
}
}
class Student implements Serializable //如果将implements Serializable 注释掉,则程序编译时就会报错
{
public String sname = null;
public int sid = 0;
transient public float sscore = 0; //表示sscore成员不能被序列化,所谓不能被序列化就是指:“该成员调用ObjectOutputStream 的writeOnbject()时不会被保存,调用ObjectInputStream的readObject()方法时不会被读取”
public Student(String name, int id, float score)
{
this.sname = name;
this.sid = id;
this.sscore = score;
}
}
输出为
ss2.sname = zhansan
ss2.sid = 1000
ss2.sscore = 0.0