Java IO编程
java i/o原理
基本概念:
?I/O(Input/Output)
?数据源(Data Source)
?数据宿(Data Sink)
Java中把不同的数据源与程序间的数据传输都抽象表述为"流"(Stream),java.io包中定义了多种I/O流类型实现数据I/O功能。
I/O流分类:
?输入流(Input Stream)和输出流(Output Stream)
?节点流(Node Stream)和处理流(Processing Stream)
?字符流(Character Stream)和字节流(Byte Stream)
输入流和输出流
按照数据流动的方向,java流可分为输入流(Input Stream)和输出流(Output Stream)
?输入流只能从中读取数据,而不能向其写出数据;
?输出流则只能向其写出数据,而不能从中读取数据
?特例:java.io.RandomAccessFile类
节点流和处理流
根据数据流所关联的是数据源还是其他数据流,可分为节点流(Node Stream)和处理流(Proce ssing Stream)
?节点流直接连接到数据源
?处理流是对一个已存在的流的连接和封装,通过封装的流的功能调用实现增强的数据读/写功能,处理流并不直接连接到数据源.
字符流和字节流
按传输数据的"颗粒大小"划分,可分为字符流(Character Stream)和字节流(Byte Stream)
?字节流以字节为单位进行数据传输,每次传送一个或多个字节;
?字符流以字符为单位进行数据传输,每次传送一个或多个字符.
Java命名惯例:
凡是以InputStream或OutputStream结尾的类型均为字节流,
凡是以Reader或Writer结尾的均为字符流。
InputStream
抽象类java.io.InputStream是所有字节输入流类型的父类,该类中定义了以字节为单位读取数据的基本方法,并在其子类中进行了分化和实现.
三个基本的read方法:
?int read()
?int read(byte[] buffer)
?int read(byte[] buffer,int offset,int length)
其他方法:
?void close()
?int available()
?skip(long n)
?boolean markSupported()
InputStream类层次
OutputStream
java.io.OutputStream与java.io.InputStream对应,是所有字节输出流类型的抽象父类。
三个基本的write方法:
?void write(int c)
?void write(byte[] buffer)
?void write(byte[] buffer,int offse t,int length)
其他方法:
?void close()
?void flush()
OutputStream类层次
Reader
抽象类java.io.Reader是所有字符输入流类型的父类,其中声明了用于读取字符流的有关方法.三个基本的read方法:
?int read()
?int read(char[] cbuf)
?int read(char[] cbuf,int offse t,int length)
其他方法:
?void close()
?boolean ready()
?skip(long n)
?boolean markSupported()
?void mark(int readAheadLimit)
?void reset()
Reader类层次
Writer
java.io.Writer与java.io.Reader类对应,是所有字符输出流类型的共同父类.五个基本的write方法:
?void write(int c)
?void write(char[] cbuf)
?void write(char[] cbuf,int offse t,int leng)
?void write(String string)
?void write(String string,int offset,int length)
其它方法:
?void close()
?void flush()
Writer类层次
常用I/O流类型
FileInputStream/FileOutputStream
FileInputStream用于读取本地文件中字节数据,FileOutputStram用于将字节数据写到文件.使用字节流实现文件的复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile{
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream ("a.jpg");
FileOutputStream fos = new FileOutputStream ("temp.jpg");
int read = fis.read();
while ( read != -1 ) {
fos.write(read);
read = fis.read();
}
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileReader/FileWriter
FileReader用于以字符为单位读取文本文件,FileWriter类用于将字符数据写到文本文件中使用字符流实现文件的复制
import java.io.*;
public class Test {
public static void main(String[] args) {
try {
FileReader input = new FileReader("a.txt");
FileWriter output = new FileWriter("temp.txt");
int read = input.read();
while ( read != -1 ) {
output.write(read);
read = input.read();
}
input.close();
output.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
BufferedReader/BufferedWriter
BufferedReader用于缓冲读取字符,BufferedWriter则是供字符的缓存写出功能.使用字符处理流实现文件的复制
import java.io.*;
public class Test {
public static void main(String[] args) {
try {
FileReader input = new FileReader("Test.java");
BufferedReader br = new BufferedReader(input);
FileWriter output = new FileWriter("temp.txt");
BufferedWriter bw = new BufferedWriter(output);
String s = br.readLine();
while ( s!=null ) {
bw.write(s);
bw.newLine();
s = br.readLine();
}
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputStreamReader
?InputStreamReader可封装字节输入流并从中读取字节数据,然后将之转换为字符.
?转换时所使用的字符编码可以在构造方法中显示指定,也可以使用平台的默认字符编码,其构造方法格式为:
?public InputStreamReader(InputStream in)
?public InputStreamReader(InputStream in,String enc)
OutputStream Writer
?与InputStreamReader对应,OutputStreamWriter可按照特定的字符编码规则把字符转化为字节并写出到它所封装的字节输出流.
PrintStream
?PrintStream在OutputStream基础之上提供了增强的功能,即可以方便地输出各种类型数据(而不仅限于byte型)的格式化表示形式.
?PrintStream的方法从不抛出IOException
PrintWriter
?PrintWriter提供了PrintStream的所有打印方法,其方法也从不抛出IOException、
?与PrintStream的区别:作为处理流使用时,PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream,还能够封装writer类型字符输出流并增强其功能
DataInputStream/DataOutputStream
?二者分别实现DataInput/DataOutput接口
?DataInputStream能够以一种与机器无关的方式,直接从底层字节输入流读取java基本类型和String类型的数据.
?DataOutputStream则能够直接将java基本类型和String类型数据写出到其他的字节输出流。
public static void main(String[] args){
try{
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String s ;
while((s=br.readLine()) != null){
System.out.println(s);
}
}catch(IOException e){
CharArrayWriter cw = new CharArrayWriter();
PrintWriter pw = new PrintWriter(cw,true);
e.printStackTrace(pw);
//char[] ca = cw.toCharArray();
String info = cw.toString();
Date time = new Date();
//将time和info信息写入数据库---
System.out.println("出错时间: " + time);
System.out.println("错误信息:\n" + info);
}
}
}
标准I/O重定向
标准输入重定向
import java.io.*;
public class TestSetInput{
public static void main(String[] args){
try{
//FileInputStream fis = new FileInputStream("source.txt");
//System.setIn(fis);
int avg = 0;
int total = 0;
int count = 0;
int num = 0;
int i;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
while(s != null && !s.equals("over")){
i = Integer.parseInt(s);
num++;
total += i;
avg = total/num;
System.out.println("num=" + num + "\ttotal=" + total + "\tavg=" + avg);
s = br.readLine();
标准输出/标准错误输出重定向
import java.io.*;
import java.util.Date;
public class TestSetOutput{
public static void main(String[] args){
PrintStream ps = null;
PrintStream ps_error = null;
try{
ps = new PrintStream(new FileOutputStream("output.txt",true));
System.setOut(ps);
ps_error = new PrintStream(new FileOutputStream("errorLog.txt",true));
System.setErr(ps_error);
int avg = 0;
int total = 0;
int count = 0;
int num = 0;
int i;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
while(s != null && !s.equals("over")){
i = Integer.parseInt(s);
num++;
total += i;
avg = total/num;
System.out.println("num=" + num + "\ttotal=" + total + "\tavg=" + avg);
s = br.readLine();
}
}catch(Exception e){
System.err.println("出错时间: " + new Date());
System.err.print("错误信息:");
e.printStackTrace(System.err);
}finally{
try{
ps.close();
ps_error.close();
实现文件随即存/取操作
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class TestRandomAccessFile{
private File file;
public static void main(String[] args){
TestRandomAccessFile traf = new TestRandomAccessFile();
traf.init();
traf.record("Billy",22);
traf.listAllRecords();
}
public void record(String record_breaker, int times){
try{
RandomAccessFile raf = new RandomAccessFile(file,"rw");
boolean flag = false;
while(raf.getFilePointer() < raf.length()){
String name = raf.readUTF();
if(record_breaker.equals(name)){
raf.writeInt(times);
flag = true;
break;
}else{
raf.skipBytes(4);
}
}
if(!flag){
raf.writeUTF(record_breaker);
raf.writeInt(times);
}
raf.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void init(){
if(file == null){
file = new File("record.txt");
try{
file.createNewFile();
}catch(IOException e){
e.printStackTrace();
}
}
}
public void listAllRecords(){
try{
RandomAccessFile raf = new RandomAccessFile(file,"r");
while(raf.getFilePointer() < raf.length()){
String name = raf.readUTF();
int times = raf.readInt();
System.out.println("name:" + name + "\trecord:" + times);
}
raf.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
使用临时文件
import java.io.*;
import java.awt.event.*;
import javax.swing.*;
public class TestTempFile implements ActionListener{
private File tempPath;
public static void main(String args[]){
TestTempFile ttf = new TestTempFile();
ttf.init();
ttf.createUI();
}
public void createUI(){
JFrame frame = new JFrame();
JButton jb = new JButton("创建临时文件");
jb.addActionListener(this);
frame.add(jb,"North");
frame.setSize(200,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void init(){
tempPath = new File("temp");
if(!tempPath.exists() || !tempPath.isDirectory()){
tempPath.mkdir(); //如果不存在,则创建该文件夹
}
}
public void actionPerformed(ActionEvent e){
try {
//在tempPath路径下创建临时文件"mytempfileXXXX.tmp"
//XXXX 是系统自动产生的随机数, tempPath对应的路径应事先存在
File tempFile=File.createT empFile("mytempfile",".txt",null);
System.out.println(tempFile.getAbsolutePath());
FileWriter fout=new FileWriter(tempFile);
PrintWriter out=new PrintWriter(fout);
out.println("some info!" );
out.close(); //注意:如无此关闭语句,文件将不能删除
//tempFile.delete();
tempFile.deleteOnExit();
}
catch(IOException e1){
System.out.println(e1);
}
}
}