java的输入输出流,在工作的时候经常遇到,有时候看别人的代码,遇到类似的知识又不怎么能看懂,上网查一知半解,过几天又忘了,本次专门学习了相关知识,顺便记录下来,方便以后查看。
一、IO流的分类
读取一个文件,输入流
写入一个文件,输出流
根据操作文件的不同,又可以分为字节流和字符流。
1、字符流是专门用来读写文本文件的(记事本打开的文件,txt java sql html xml等)查询本机上的编码表(GBK)。
输入流,读取文件的抽象基类,Reader
输出流,写入文件的抽象基类,Writer
2、字节流,操作的是计算机上的字节,计算机上最小的存储单位,可以操作计算机上的任意文件(文件夹除外)。
输入流,读取文件的抽象基类,InputStream
输出流,写入文件的抽象基类,OutputStream
二、使用FileWriter写入一个文件
import java.io.*;
public class FileWriterDemo {
public static void main(String[] args)throws IOException {
/*
* 创建了一个对象 new FileWriter对象
* 抛出异常
* 在目的中,创建了一个文件
* 文件的创建,是依靠Windows操作系统创建出来的
* 如果文件已经存在了,覆盖原有文件
*/
FileWriter fw = new FileWriter("c:\\f.txt");
//写入数据了
fw.write("hello io");
//刷新流中的缓冲
//fw.flush();
fw.write("java world");
//fw.flush();
fw.close();
}
}
注意:在创建新的文件时,会覆盖掉原来的文件。java字符流在写入文件的时候,不会直接写到文件中,而是写到内存中,因此要用flush刷新后才能写入文件。
流对象的功能是调用Windows系统中的功能来完成的,因此在释放Windows系统资源(关闭流)之前,即close()方法之前,会刷新流中的数据,因此也可不必用flush方法来刷新,但是当数据特别多的时候,最好还是写一句,刷一局。
三、使用FileWriter写一个字符数组
import java.io.*;
public class FileWriterDemo2 {
public static void main(String[] args) {
FileWriter fw = null;
try{
fw = new FileWriter("c:\\f.txt");
//建立字符数组
char[] ch = {'a','q','你','好'};
//写数组
fw.write(ch, 0, ch.length);
}catch(IOException e){
throw new RuntimeException("文件写入失败");
}finally{
try{
if(fw!=null)
fw.close();
}catch(IOException e){
throw new RuntimeException("写入关闭失败");
}
}
}
}
四、使用FileReader读字符
import java.io.*;
public class FileReaderDemo {
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("c:\\f.txt");
//调用read方法进行读取操作,返回int值
int len = 0 ;
//read读取到末尾返回-1,利用循环读取
while((len = fr.read())!=-1){
//看到字符,将读取到的int值,转成char值
System.out.print((char)len);
}
fr.close();
}
}
read方法读取单个字符,每执行一次,自动向后读取下一个字符,每次读取返回的是int值,是字符的ASSCII码值。所以这里用循环的方式,循环的读取文件,并且将读取到的len强转为char输出。当文件被读完,返回的是-1.
五、使用FileReader读取数组
import java.io.*;
public class FileReaderDemo1 {
public static void main(String[] args) {
FileReader fr = null;
try{
fr = new FileReader("C:\\intel");
//定义字符数组
char[] buf = new char[1024];//2KB
int len = 0 ;
while((len = fr.read(buf))!=-1){
System.out.print(new String(buf,0,len));
}
}catch(IOException e){
throw new RuntimeException("文件读取失败");
}finally{
try{
if(fr!=null)
fr.close();
}catch(IOException e){
throw new RuntimeException("读取关闭失败");
}
}
}
}
read(数组),此方法返回的Int值,是读到的字符的有效个数,当文件督导末尾的时候,返回-1。数组中存储的就是读到的文件中的字符。此方法的好处在于比read读取单个字符的效率要高。
六、写入流的缓冲区对象BufferedWriter
使用BufferedWriter(Writer out)写入数据
import java.io.*;
public class BufferedWriterDemo {
public static void main(String[] args)throws IOException {
//字符输出流对象
FileWriter fw = new FileWriter("c:\\f.txt");
//建立缓冲区对象,提高输出流的效率
BufferedWriter bfw = new BufferedWriter(fw);
//写一行,换一行
bfw.write("哈哈");
bfw.newLine();
bfw.write("嘻嘻");
bfw.flush();
bfw.close();
}
}
七、读取流的缓冲区对象BufferedReader
使用BufferedReader(Reader in)读取数据
import java.io.*;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException{
//建立字符读取流对象
FileReader fr = new FileReader("c:\\s.log");
//建立缓冲区对象
BufferedReader bfr = new BufferedReader(fr);
//读取一行,返回字符串,末尾就返回null
String line = null;
while((line = bfr.readLine())!=null){
System.out.println(line);
}
bfr.close();
}
}
八、使用字符流,完成一个复制的功能
package cn.itcast.iostream;
/*
* 两种方式复制文本文件
* 定义三个方法完成
* 第一个方法,复制,读一个字符,写一个字符
* 第二个方法,复制,读一个数组,写一个数组
* 第三个方法,复制,读一行,写一行
*/
import java.io.*;
public class CopyText {
public static void main(String[] args) {
//获取程序运行开始的毫秒值
long start = System.currentTimeMillis();
copy_3();
//获取结束的毫秒值
long end = System.currentTimeMillis();
System.out.println(end - start);
}
//读取一行,写一行,利用的是缓冲区对象
private static void copy_3(){
BufferedReader bfr = null;
BufferedWriter bfw = null;
try{
bfr = new BufferedReader(new FileReader("c:\\s.log"));
bfw = new BufferedWriter(new FileWriter("d:\\s.log"));
String line = null;
while((line = bfr.readLine())!=null){
bfw.write(line);
bfw.newLine();
bfw.flush();
}
}catch(IOException e){
throw new RuntimeException("复制失败");
}finally{
try{
if(bfw!=null)
bfw.close();
}catch(IOException e){
throw new RuntimeException("文件写入关闭失败");
}
try{
if(bfr!=null)
bfr.close();
}catch(IOException e){
throw new RuntimeException("文件读取关闭失败");
}
}
}
//读取一个数组,写一个数组
private static void copy_2(){
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("c:\\s.log");
fw = new FileWriter("d:\\s.log");
int len = 0 ;
//定义数组
char[] buf = new char[1024];
while((len = fr.read(buf))!=-1){
fw.write(buf,0,len);
}
}catch(IOException e){
throw new RuntimeException("文件复制失败");
}finally{
try{
if(fw!=null)
fw.close();
}catch(IOException e){
throw new RuntimeException("写入关闭失败");
}
try{
if(fr!=null)
fr.close();
}catch(IOException e){
throw new RuntimeException("读取关闭失败");
}
}
}
//读取一个字符,写一个字符
private static void copy_1(){
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("c:\\s.log");
fw = new FileWriter("d:\\s.log");
int len = 0 ;
while((len = fr.read())!=-1){
fw.write((char)len);
}
}catch(IOException e){
throw new RuntimeException("文件复制失败");
}finally{
try{
if(fw!=null)
fw.close();
}catch(IOException e){
throw new RuntimeException("写入关闭失败");
}
try{
if(fr!=null)
fr.close();
}catch(IOException e){
throw new RuntimeException("读取关闭失败");
}
}
}
}
====================================================================================
以上都是字符流,下面看下字节流。字节流和字符流在使用上并无区别,都是read()和writer()方法。但是字节流操作的是字节。一下就举一个列子加以区别。
九、使用字节流实现复制文件的功能
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws IOException{
//建立字节输入流对象,读取源文件
FileInputStream fis = new FileInputStream("c:\\language.rar");
//建立字节输出流对象,写目的文件
FileOutputStream fos = new FileOutputStream("d:\\language.rar");
/*
* 开始进行复制
* 输入流对象,源文件的读取,读取后存储到字节数组中
* 输出流对象,写目的文件,数组中存储的字节写到文件中
*/
byte[] bytes = new byte[1024];
int len = 0 ;
while((len = fis.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
}
}
十、InputStreamReader和OutputStreamWriter
利用InputStreamReader和OutputStreamWriter可以将字节流转换成字符流,从而使用BufferedReader和BufferedWriter进行读取行和写入行的操作。
下面是一个将键盘输入的字符,写入到文件中的一个例子。
public class TranseDemo {
public static void main(String[] args)throws IOException {
//返回字节输入流对象
InputStream in = System.in;
//使用转换流,将字节输入流,转成字符输入流
InputStreamReader isr = new InputStreamReader(in);
//使用字符流的缓冲区,进行行的读取
BufferedReader bfr = new BufferedReader(isr);
OutputStream out = new FileOutputStream("c:\\stream.txt");
//将字节流,转成了字符流
OutputStreamWriter osr = new OutputStreamWriter(out);
//可以使用字符流的缓冲区,进行数据的输出,输出行
BufferedWriter bfw = new BufferedWriter(osr);
String line = null ;
while((line = bfr.readLine())!=null){//"null"
if("over".equals(line))
break;
bfw.write(line.toUpperCase());
bfw.newLine();
bfw.flush();
}
bfw.close();
bfr.close();
}
}