------- android培训、java培训、期待与您交流! ----------
在变量、数组和对象中存储的数据是暂时存在的,程序结束后它们就会丢失。为了能够永久的保存程序创建的数据,需要将其保存在磁盘文件中,这样就可以在其它程序中使用它们。Java的I/O技术可以将数据保存到文本文件、二进制文件甚至是ZIP压缩文件中,以达到永久性保存数据的要求。
1、IO流用来处理设备之间的数据传输。
2、Java对数据的操作是通过流的方式。
3、Java用于操作流的对象都封装在IO包中。
4、流按操作数据分为两种:字节流与字符流。
5、流按流向分为:输入流,输出流。
IO
字符流的抽象基类: Reader,Writer
字节流的抽象基类 : InputStream,OutputStream
IO流体系
Reader类的层次结构:
Writer类的层次结构:
InputStream类的层次结构:
OutputStream类的层次结构:
文本写入
writer抽象类
abstract void
close()
关闭此流,但要先刷新它。abstract void
flush()
刷新该流的缓冲。void
write(char[] cbuf)
写入字符数组。abstract void
write(char[] cbuf, int off, int len)
写入字符数组的某一部分。void
write(int c)
写入单个字符。void
write(String str)
写入字符串。void
write(String str, int off, int len)
写入字符串的某一部分。
FileWriter类
构造方法摘要
FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。
/*
需求:在硬盘上,创建一个文件并写入一些文字数据。
找到一个专门用于操作文件的Writer子类对象--FileWriter。 后缀名是父类名, 前缀名是该流对象的功能。
*/
import java.io.Writer;
import java.io.FileWriter;
import java.io.IOException;
public class Test{
public static void main(String...args)throws IOException{
/*创建一个FileWriter对象,该对象一被初始化,就必须要明确被操作的文件.
而且该文件会被创建到指定目录下,如果该目录下已有同名的文件,将被覆盖。
其实该步就是明确数据要存放的目的地*/
Writer w = new FileWriter("1.Java");
/*调用writer方法,将字符串写入到流中,会抛IO异常.*/
w.write("黑马程序员");
/*刷新该流的缓冲。将数据刷新到文件中*/
w.flush();
/*关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
将数据刷到目的地中。
和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。*/w.close();
}
}
IO流(文本文件读取方式一)
Reader抽象类
int
read()
读取单个字符。
abstract void
close()
关闭该流并释放与之关联的所有资源。
构造方法摘要
FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。
import java.io.Reader;
import java.io.FileReader;
import java.io.IOException;
public class Test{
public static void main(String...args) throws IOException{
/*
创建一个文件读取流对象,和指定名称的文件相关联。
要保证该文件是已经存在的,如果不存在,会发生异常 FileNotFoundException
*/
Reader r = new FileReader("C:\\1.Java");
int ch =0;
while((ch=r.read())!=-1){
System.out.print((char)ch);
}
}
}
IO流(文本文件读取方式二)
Reader抽象类
int
read(char[] cbuf)
将字符读入数组。import java.io.Reader;
import java.io.FileReader;
import java.io.IOException;
public class Test{
public static void main(String...args) throws IOException{
Reader r = new FileReader("C:\\1.Java");
char[]buf = new char[1024];
int len =0;
while((len=r.read(buf))!=-1){
sop(new String(buf,0,len));
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
IO流(拷贝文本文件)
复制的原理,其实就是将一个文件的数据存储到另一个文件中
/*
1、在C盘创建一个文件,用于存储C盘文件中的数据
2、定义读取流和C盘文件关联
3、通过不断的读写完成数据存储
4、关闭资源
*/
import java.io.IOException;
import java.io.Writer;
import java.io.Reader;
import java.io.FileWriter;
import java.io.FileReader;
public class Test{
public static void main(String... args){
Reader r =null;
Writer w =null;
try{
r = new FileReader("C:\\1.Java");
w =new FileWriter("C:\\2.Java");
char[] buf =new char[1024];
for(int len=0;(len=r.read(buf))!=-1;){
w.write(new String(buf,0,len));
}
}
catch(IOException e){
System.out.println(e);
}
finally{
try{
if(r!=null)
r.close();
}catch(IOException e){
System.out.println(e);
}
finally{
try{
if(w!=null)
w.close();
}
catch(IOException e){
System.out.println(e);
}
}
}
}
}
字符流的缓冲区
1、缓冲区的出现提高了对数据的读写效率。
2、对应类。
(1) BufferedWriter
3、缓冲区要结合流才可以使用。(2) BufferedReader
4、在流的基础上对流的功能进行了增强。
BufferWriter
void
newLine()
写入一个行分隔符。
/* 缓冲区的出现是为了提高流的操作效率而出现的 所以在创建缓冲区之前,必须要先有流对象。 */ import java.io.IOException; import java.io.Writer; import java.io.FileWriter; import java.io.BufferedWriter; public class Test{ public static void main(String...args) throws IOException{ Writer w = new FileWriter("C:\\1.Java"); /* 为了提高字符写入流的效率,加入了缓冲技术,只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可 */ BufferedWriter bw = new BufferedWriter(w); bw.write("黑马程序员"); /* 当然如果要刷新的话,当然是要刷新缓存区的flush, 因为数据写到缓冲区里面去了。 如果刷新流对象是刷不出来东西的。关闭也一样 */ bw.newLine(); bw.write("我来了"); bw.flush(); //bw.close(); /*其实这个流可以不用关闭也行。因为缓存区必须有流,而流对象关闭了。 缓存区对象也就自动释放了*/ w.close(); } }
BufferedReader
String
readLine()
读取一个文本行。
readLine() 读取一个文本行。返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null ,所有要手动写入换行.
/* 字符读取流缓冲区: 该缓冲区提供了一个一次读一行的方法 readLine ,方便于对文本数据的获取 当返回 null 时,表示读到文件的末尾 readLine() 方法返回的时候只返回回车符之前的数据内容,并不返回回车符 */ import java.io.Reader; import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; public class Test{ public static void main(String...args) throws IOException{ Reader r = new FileReader("C:\\1.Java"); /* 为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数 */ BufferedReader br = new BufferedReader(r); for(String line = null;(line=br.readLine())!=null;){ System.out.print(line); System.out.println(); } } }
IO流(通过缓冲区复制文本文件)
/* 通过缓冲区复制一个 .Java 文件 */ import java.io.IOException; import java.io.BufferedWriter; import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; public class Test{ public static void main(String...args){ BufferedReader br = null; BufferedWriter bw = null; try{ br =new BufferedReader(new FileReader("C:\\1.Java")); bw = new BufferedWriter(new FileWriter("C:\\2.Java")); for(String line = null;(line=br.readLine())!=null;){ bw.write(line); bw.newLine(); bw.flush(); } } catch(IOException e){ throw new RuntimeException("读写失败"); } finally{ try{ if(br!=null) br.close(); } catch(IOException e){ throw new RuntimeException("读取关闭失败"); } try{ if(bw!=null) bw.close(); } catch(IOException e){ throw new RuntimeException("写入关闭失败"); } } } }
LineNumberReader
int
getLineNumber()
获得当前行号。
void
setLineNumber(int lineNumber)
设置当前行号。import java.io.BufferedReader; import java.io.FileReader; import java.io.LineNumberReader; import java.io.IOException; public class Test{ public static void main(String... args) throws IOException{ BufferedReader br = new BufferedReader(new FileReader("C:\\1.Java")); LineNumberReader lnr = new LineNumberReader(br); lnr.setLineNumber(100); for(String line =null;(line=lnr.readLine())!=null;){ System.out.println(lnr.getLineNumber()+":"+line); } lnr.close(); } }
字节流基类
InputStream
OutputStream
/* 写入文件 */ import java.io.OutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test{ public static void main(String...args)throwsIOException{ OutputStream os = new FileOutputStream("C:\\1.Java"); os.write("黑马程序员".getBytes()); os.close(); } } /* 第一种读取文件的方法。 对于操作文本文件不支持使用此做法。 */ import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; public classTest{ public static void main(String...args) throws IOException{ InputStream is =newFileInputStream("C:\\1.jpg"); for(int by = 0;(by=is.read())!=-1;){ System.out.print(by); } is.close(); } } /* 第二种读取文件的方法。 对于操作文本文件支持使用此做法。 */ import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; public class Test{ public static void main(String...args) throws IOException{ InputStream is = new FileInputStream("C:\\1.Java"); byte []buf = new byte[1024]; for(int len = 0;(len=is.read(buf))!=-1;){ System.out.print(new String(buf,0,len)); } is.close(); } }
InputStream
int
available()
返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
/* 第三种方式,如果内存太大会报错。 */ import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; public class Test{ public static void main(String...args) throws IOException{ InputStream is =new FileInputStream("C:\\1.Java"); byte[] buf =new byte[is.available()]; is.read(buf); System.out.println(new String(buf)); is.close(); } }
IO流(拷贝图片)
思路:
1、用字节读取流对象和图片关联
2、用字节写入流对象创建一个图片文件。用于存储获取到的图片数据
3、通过循环读写,完成数据的存储
4、关闭资源
import java.io.InputStream; import java.io.FileInputStream; import java.io.OutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test{ public static void main(String...args){ InputStream is =null; OutputStream os =null; try{ is =newFileInputStream("C:\\1.jpg"); os =newFileOutputStream("D:\\1.jpg"); byte []buf =new byte[1024]; for(int len=0;(len=is.read(buf))!=-1;){ os.write(buf,0,len); } } catch(IOException e){ System.out.println("读写错误"); } finally{ try{ if(is!=null) is.close(); } catch(IOException e){ System.out.println("读取流关闭失败"); } finally{ try{ if(os!=null) os.close(); } catch(IOException e){ System.out.println("写入流关闭失败"); } } } } }
字节流缓冲区
BufferedInputStream
BufferedOutputStream
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; public class Test{ public static void main(String...args)throws IOException{ BufferedInputStream is = new BufferedInputStream (new FileInputStream("C:\\1.mp3")); BufferedOutputStream os = new BufferedOutputStream (new FileOutputStream("D:\\1.mp3")); for(int by = 0;(by=is.read())!=-1;){ os.write(by); } is.close(); os.close(); } }
/* 需求:将键盘录入的数据输出到一个文本文件中, 如果录入数据是over,那么停止录入,否则就输入到文件中 */ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.IOException; public class Test{ public static void main(String...args)throws IOException{ BufferedReader bufr =new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw =new BufferedWriter(new OutputStreamWriter (new FileOutputStream("C:\\1.Java"))); for(String line = null;(line=bufr.readLine())!=null;){ if("over".equals(line)) break; bufw.write(line); bufw.newLine(); bufw.flush(); } bufr.close(); bufw.close(); } }
流对象有很多,到底该用哪一个呢?
(1) 明确源和目的
源:输入流InputStream Reader
目的:输出流OutputStream Writer
(2) 操作的数据是否是纯文本
是:字符流 Reader Writer
不是:字节流 InputStream OutputStream
(3) 当体系明确后,再明确要使用那个具体的对象
通过设备来进行区分:
源设备:内存 硬盘 键盘
目的设备:内存 硬盘 控制台