Java基础之IO流处理

来源:互联网 发布:windows defender 评测 编辑:程序博客网 时间:2024/05/16 06:00

IOInput/Output)是计算机输出/输出的接口。JavaIO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。此外,Java也对块传输提供支持,在核心库java.nio中采用的便是块IOJavaIO模型设计使用Decorator模式,体系分Input/OutputReader/Writer两类,区别在于Reader/Writer在读写文本时能自动转换内码。

 

javaIO包类分层结构:

java.lang.Object

java.io.File

java.io.InputStream

  java.io.FileInputStream

  java.io.FilterInputStream

       java.io.BufferedInputStream

       java.io.DataInputStream

java.io.OutputStream

  java.io.FileOutputStream

  java.io.FilterOutputStream

     java.io.BufferedOutputStream

      java.io.DataOutputStream

  java.io.PrintStream

java.io.RandomAccessFile

java.io.Reader

  java.io.BufferedReader

  java.io.InputStreamReader

       java.io.FileReader

java.io.Writer

    java.io.BufferedWriter

    java.io.OutputStreamWriter

       java.io.FileWriter

    java.io.PrintWriter

 

从输入流读数据的过程一般如下:
open a stream
while more information
    read information

close the stream

类似地,程序也能通过打开一个输出流并顺序地写入数据来将信息送至目的端。
往输出流写数据的过程一般如下:
open a stream
while more information 
    write information

close the stream

 

先来看看I/O应用的几个例子
import java.io.*;
public class TestIO{
public static void main(String[] args) throws IOException{
//以行为单位从一个文件读取数据
/*当读取文件时,先把文件内容读到缓存中,当调用in.readLine()时,
再从缓存中以字符的方式读取数据(以下简称“缓存字节读取方式”)。
*/
BufferedReader in = new BufferedReader(new FileReader("F://java//TestIO.java"));
String s1, s2 = new String();
while((s1 = in.readLine()) != null)
s2 += s1 + "/n";
in.close();

// 接收键盘的输入
/*由于想以缓存字节读取方式从标准IO(键盘)中读取数据,所以要
先把标准IO(System.in)转换成字符导向的stream,再进行BufferedReader封装。
*/
BufferedReader kbin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter a line:");
System.out.println(kbin.readLine());

 

// 从一个String对象中读取数据
/*
要以字符的形式从一个String对象中读取数据,所以要产生一个StringReader类型的stream。
*/
StringReader in = new StringReader(s);
int c;
while((c = in.read()) != -1)
System.out.println((char)c);
in.close();

 

//从内存取出格式化输入
//把内存中的一个缓冲区作为DataInputStream使用

try{
DataInputStream in = new DataInputStream(new ByteArrayInputStream(s.getBytes()));
while(true)
System.out.println((char)in.readByte());
}catch(EOFException e){
System.out.println("End of stream");
}

 

// 输出到文件
/*对String对象s读取数据时,先把对象中的数据存入缓存中,再从缓冲中进行读取;对TestIO.out文件进行操作时,
先把格式化后的信息输出 到缓存中,再把缓存中的信息输出到文件中。
*/
try{
BufferedReader in = new BufferedReader(new StringReader(s));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("F://java// TestIO.out")));
int lineCount = 1;
while((s = in.readLine()) != null)
out.println(lineCount++ + ":" + s);
out.close();
in.close();
} catch(EOFException ex){
ystem.out.println("End of stream");
}

 

// 数据的存储和恢复
/*对Data.txt文件进行输出时,是先把基本类型的数据输出屋缓存中,再把缓存中的数据输出到文件中;对文件进行读取操作时,先把文件中的数据读取到缓存中,再从缓存中以基本类型的形式进行读取。注意in5.readDouble()这一行。因为写入第一个writeDouble(),所以为了正确显示。也要以基本类型的形式进行读取。
*/
try{
DataOutputStream out = new DataOutputStream(new BufferedOutputStream( new FileOutputStream("F://java// Data.txt")));
out.writeDouble(3.1415926);
out.writeChars("/nThas was pi:writeChars/n");
out.writeBytes("Thas was pi:writeByte/n");
out.close();
DataInputStream in = new DataInputStream( new BufferedInputStream(new FileInputStream("F://java// Data.txt")));
BufferedReader br = new BufferedReader( new InputStreamReader(in));
System.out.println(in.readDouble());
System.out.println(br.readLine());
System.out.println(br.readLine());
} catch(EOFException e){
System.out.println("End of stream");
}

 

//通过RandomAccessFile类对文件进行操作。
RandomAccessFile rf =new RandomAccessFile("F://java// r.dat", "rw");
for(int i=0; i<10; i++)
rf.writeDouble(i*1.414);
rf.close();

rf = new RandomAccessFile("F://java// r.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();

rf = new RandomAccessFile("F://java// r.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();

rf = new RandomAccessFile("F://java// r.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + ":" + rf.readDouble());
rf.close();

InputStream的方法有:
read() 从流中读入数据有3中方式:
int read() 一次读一个字节
int read(byte[]) 读多个字节到数组中
int read(byte[],int off,int len) 指定从数组的哪里开始,读多长
skip() 跳过流中若干字节
available() 返回流中可用字节数,但基于网络时无效,返回0
markSupported() 判断是否支持标记与复位操作
mark() 在流中标记一个位置,要与markSupported()连用
reset() 返回标记过的位置
close() 关闭流

OutputStream 的方法:
write(int) 写一个字节到流中
write(byte[]) 将数组中的内容写到流中
write(byte[],int off,int len) 将数组中从off指定的位置开始len长度的数据写到流中
close() 关闭流
flush() 将缓冲区中的数据强制输出

File 类
File 可以表示文件也可以表示目录,File 类控制所有硬盘操作
构造器:
File(File parent,String child) 用父类和文件名构造
File(String pathname) 用绝对路径构造
File(String parent,String child) 用父目录和文件名构造
File(URI uri) 用远程文件构造
常用方法:
boolean createNewFile();
boolean exists();
例子:
//建立 test.txt 文件对象,判断是否存在,不存在就创建
import java.io.*;
public class CreateNewFile{
public static void main(String args[]){
File f=new File("test.txt");
try{
if(!f.exists())
f.createNewFile();
else
System.out.println("exists");
}catch(Exception e){
e.printStackTrace();
}
}
}
boolean mkdir()/mkdirs()
boolean renameTo(File destination)
例子://看一下这 mkdir()/mkdirs() 的区别和 renameTo 的用法
import java.io.*;
public class CreateDir{
public static void main(String args[]){
File f=new File("test.txt");
File f1=new File("Dir");
File f2=new File("Top/Bottom");
File f3=new File("newTest.txt");
try{
f.renameTo(f3);
f1.mkdir();
f2.mkdirs();
}catch(Exception e){
e.printStackTrace();
}
}
}
String getPath()/getAbsolutePath()
String getParent()/getName()
例子://硬盘上并没有parent 目录和 test.txt 文件,但我们仍然可以操作,因为我们创建了他们的对象,是对对象进行操作
import java.io.*;
public class Test{
public static void main(String args[]){
File f=new File("parent/test.txt");
File f1=new File("newTest.txt");
try{
System.out.println(f.getParent());
System.out.println(f.getName());
System.out.println(f1.getPath());
System.out.println(f1.getAbsolutePath());
}catch(Exception e){
e.printStackTrace();
}
}
}
String list[] //显示目录下所有文件
long lastModified() //返回 1970.1.1 到最后修改时间的秒数
boolean isDirectory()
例子://列出目录下的所有文件和目录,最后修改时间,是目录的后面标出
,是文件的后面标出文件长度
import java.io.*;
import java.util.*;
public class Dir{
public static void main(String args[]){
File f=new File("Dir");
String[] listAll=null;
File temp=null;
try{
listAll=f.list();
for(int i=0;itemp=new File(listAll);
System.out.print(listAll+"/t");
if(temp.isDirectory())
System.out.print("/t
/t");
else
System.out.print(temp.length()+"/t");
System.out.println(new Date(temp.lastModified()));
}
}catch(Exception e){
e.printStackTrace();
}
}
}

 

文件流的建立
File f=new File("temp.txt");
FileInputStream in=new FileInputStream(f);
FileOutputStream out=new FileOutputStream(f);
例子:文件拷贝
import java.io.*;
public class Copy{
public static void main(String args[]){
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis=new FileInputStream("c2.gif");
fos=new FileOutputStream("c2_copy.gif");
int c;
while((c=fis.read()) != -1)
fos.write(c);
}catch(Exception e){
e.printStackTrace();
}finally{
if(fis != null) try{ fis.close(); }catch(Exception e){ e.printStackTrace(); }
if(fos!= null) try{ fos.close(); }catch(Exception e){ e.printStackTrace(); }
}
}
}

 

缓冲区流
BufferedInputStream
BufferedOutputStream
他们是在普通文件流上加了缓冲的功能,所以构造他们时要先构造普通流
例子:文件拷贝的缓冲改进
import java.io.*;
public class Copy{
public static void main(String args[]){
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
byte buf[]=new byte[100];
try{
bis=new BufferedInputStream(new FileInputStream("persia.mp3"));
bos=new BufferedOutputStream(new FileOutputStream("persia_copy.mp3"));
int len=0;
while( true ){
len=bis.read(buf);
if(len<=0) break;
bos.write(buf,0,len);
}
bos.flush();//缓冲区只有满时才会将数据输出到输出流,用flush()将未满的缓冲区中数据强制输出
}catch(Exception e){
e.printStackTrace();
}finally{
if(bis != null) try{ bis.close(); }catch(Exception e){ e.printStackTrace(); }
if(bos!= null) try{ bos.close(); }catch(Exception e){ e.printStackTrace(); }
}
}
}

 

原始型数据流
DataInputStream
DataOutputStream
他们是在普通流上加了读写原始型数据的功能,所以构造他们时要先构造普通流
方法:
readBoolean()/writeBoolean()
readByte()/writeByte()
readChar()/writeByte()
......
例子://这个流比较简单,要注意的就是读时的顺序要和写时的一样
import java.io.*;
public class DataOut{
public static void main(String args[]){
DataOutputStream dos=null;
try{
dos=new DataOutputStream(new FileOutputStream("dataout.txt"));
dos.writeInt(1);
dos.writeBoolean(true);
dos.writeLong(100L);
dos.writeChar('a');
}catch(Exception e){
e.printStackTrace();
}finally{
if(dos!=null)
try{
dos.close();
}catch(Exception e){
}
}
}
}
import java.io.*;
public class DataIn{
public static void main(String args[]){
DataInputStream dis=null;
try{
dis=new DataInputStream(new FileInputStream("dataout.txt"));
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
System.out.println(dis.readLong());
System.out.println(dis.readChar());
}catch(Exception e){
e.printStackTrace();
}finally{
if(dis!=null)
try{
dis.close();
}catch(Exception e){
}
}
}
}

 


Java IO 的一般使用原则 : 

一、按数据来源(去向)分类:

1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )

2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )

3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )

4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )

5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )

二、按是否格式化输出分:

1 、要格式化输出: PrintStream, PrintWriter

三、按是否要缓冲分:

1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )

四、按数据格式分:

1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类

2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类

五、按输入输出分:

1 、输入: Reader, InputStream 类型的子类

2 、输出: Writer, OutputStream 类型的子类

六、特殊需要:

1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter

2 、对象输入输出: ObjectInputStream, ObjectOutputStream

3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter

4 、合并输入: SequenceInputStream

5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

 

原创粉丝点击