输入流:信息从程序空间之外的地方流入程序空间里面
输出流:信息从程序空间里面流到程序空间之外的地方
从流的方法划分
从流的分工划分
从流的内容划分
所有的输入输出流类都继承于以上四个类
面向字符的流的超类为Reader&Writer
面向字节的流的超类为InputStream&OutputStream
首先在该项目的文件所在位置新建一个Redirecting.txt文件
import java.io.*;
public class Redirecting {
public static void main(String[] args) throws FileNotFoundException {
BufferedInputStream in = new BufferedInputStream(
new FileInputStream("Redirecting.txt"));
//FileInputStream就是一个面向字节的流,然后再通过BufferedInputStream来转化,
//BufferedInputStream也是一个流,是一个缓冲流
PrintStream out = new PrintStream(new
BufferedOutputStream(new FileOutputStream("test.txt")));
System.setIn(in);
//将输入流重定向到Redirecting文件中,相当于本来我们是从键盘输入,现在变成从文件来输入
System.setOut(out);
//将输出流重定向到test.txt文件中,本来应该是输出到显示器上,现在输出到test文件中
System.setErr(out);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//BufferedReader是一个面向字符的流,因为BufferedReder只处理信息,但是不读取信息
//因此我们需要用一个InputStreamReader来从文件中读取信息,再由BufferedReader转换
String s;
while((s=br.readLine())!=null)
System.out.println(s);
//因为我们已经输出流定向到test.txt文件中了,所以我们这里相当于复制的操作
in.close();
out.close();
}
}
import java.io.*;
public class FileWriterTester {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String fileName = "Hello.txt";
FileWriter writer = new FileWriter(fileName);
writer.write("Hello World!");
writer.close();
}
}
如果有大量的信息要写入文件,可以使用BufferedWriter
import java.io.*;
public class FileWriterTester {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String fileName = "Hello.txt";
BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
//跟前面说的一样,BufferedWriter也不直接对文件信息进行读取,它只处文件信息
//因此我们需要用一个FileWriter来读取文件,再转换为BufferedWriter
out.write("Hello World!");
out.newLine(); //跨平台的换行,\n不一定在各个平台都是换行
out.close();
}
}
import java.io.*;
public class FileWriterTester {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String fileName = "Hello.txt";
BufferedReader in = new BufferedReader(new FileReader(fileName));
//使用BuffereReader类可以按行读取
String c = in.readLine();
while(c!=null)
{
System.out.println(c);
c=in.readLine();
}
}
}
Reader类有一个read方法,返回文件中字符的ASCLL码
import java.io.*;
public class FileWriterTester {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String fileName = "Hello.txt";
FileReader in = new FileReader(fileName);
//前面的BuffereReader类也有read方法
int c;
while((c=in.read())!=-1)
System.out.print((char)c);
}
}
写二进制文件用到的类为DataOutputStream
,继承于OutputStream
,有一个派生类为FileOutputStream
,这一个类只针对输入输出而DataoutPutStream
可以写入各种类型的数据
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputstreamTester {
public static void main(String[] args) throws FileNotFoundException, IOException{
// TODO Auto-generated method stub
String fileName = "test.dat";
DataOutputStream out = new DataOutputStream(
new FileOutputStream(fileName));
//用FileOutputStream转换为DataOutputStream
out.writeByte(-1);
out.writeByte(2);
out.writeInt(5);
out.writeBytes("Hello World");
out.close();
}
}
}
同理,为了加快写入速度,我们可以使用BufferedOutputStream
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(fileName)));
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputstreamTester {
public static void main(String[] args) throws FileNotFoundException, IOException{
// TODO Auto-generated method stub
String fileName = "test.dat";
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(fileName)));
out.writeByte(-1);
out.writeByte(2);
out.close();
int sum=0;
try
{
DataInputStream in = new DataInputStream(
new BufferedInputStream(new FileInputStream("test.dat")));
//读二进制文件用的是DataInputStream,同时使用BufferedInputStream提高读取速度
try
{
while(true)
{
sum+=in.readUnsignedByte();
}
}
catch(EOFException eof) //如果读到文件尾,就会抛出异常
{
System.out.println("The sum is:"+sum);
in.close();
}
}
catch(IOException iox) //文件读取的异常
{
System.out.println("IO Problems with"+fileName);
}
}
}
输出结果为257,因为我们读取的是无符号数in.readUnsignedByte()
,如果改成in.readByte()
,那么结果就是1
注意: 写二进制文件时,我们一般只在一个文件写入一种类型的数据,而且得用文档记录起来
一个拷贝文件的例子
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException{
if(args.length!=2)
return;
DataInputStream instr;
DataOutputStream outstr;
instr = new DataInputStream(new BufferedInputStream
(new FileInputStream(args[0]))); //源文件
outstr = new DataOutputStream(new BufferedOutputStream
(new FileOutputStream(args[1])));//目标文件
int c;
try
{
while(true)
{
c = instr.readUnsignedByte(); //读取源文件的字符
outstr.writeByte(c); //写入目标文件中
}
}
catch (EOFException eof) //读到文件为抛出异常,关闭文件
{
// TODO Auto-generated catch block
outstr.close();
instr.close();
return;
}
}
}
这里我们用的是args来传递参数的,顺便说一个args的值从哪里来
Run As
运行之后就能发现文件被复制成功了
File
类用于创建文件,比较常用的方法由File.exits()
,File.delete()
import java.io.*;
public class FileTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("hello.txt");
if(f.exists())
f.delete();
else
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果hello.txt
文件存在,就会被删除,否则就建立一个新的文件
跟前面的类似,我们使用GZIPInputStream
和GZIPOutputStream
这两个类来实现
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZIPTester {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("Hello.txt");
GZIPOutputStream out = new GZIPOutputStream(
new FileOutputStream("test.gz"));
//使用GZIPOutputStream作为输出流
System.out.println("Writing compressing file from Hello.txt to test.gz");
int c;
while((c=in.read())!=-1)
out.write(c);
//一个一个字符的写入
in.close();
out.close();
}
}
解压缩test.gz文件
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZIPTester {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("Hello.txt");
GZIPOutputStream out = new GZIPOutputStream(
new FileOutputStream("test.gz"));
System.out.println("Writing compressing file from Hello.txt to test.gz");
int c;
while((c=in.read())!=-1)
out.write(c);
in.close();
out.close();
System.out.println("Reading file from test.gz to monitor");
BufferedReader in2 = new BufferedReader(new InputStreamReader(
new GZIPInputStream(new FileInputStream("test.gz"))));
//使用GZIPInputStream来作为输入流,再使用InputSteamReader来作为面向字节到面向字符的桥梁
String s;
while((s=in2.readLine())!=null)
System.out.println(s);
//输出解压缩后的文件内容
in2.close();
也可以通过将压缩文件的内容直接写入文件实现解压缩
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZIPTester {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("Hello.txt");
GZIPOutputStream out = new GZIPOutputStream(
new FileOutputStream("test.gz"));
System.out.println("Writing compressing file from Hello.txt to test.gz");
int c;
while((c=in.read())!=-1)
out.write(c);
in.close();
out.close();
System.out.println("Reading file from test.gz to monitor");
BufferedReader in2 = new BufferedReader(new InputStreamReader(
new GZIPInputStream(new FileInputStream("test.gz"))));
String s;
while((s=in2.readLine())!=null)
System.out.println(s);
in2.close();
System.out.println("Writing decompression to newHello.txt");
GZIPInputStream in3 = new GZIPInputStream(
new FileInputStream("test.gz"));
FileOutputStream out2 = new FileOutputStream("newHello.txt");
while((c=in3.read())!=-1)
out2.write(c);
//一个一个字节的写
in3.close();
out2.close();
}
}
我们使用ZipOutputStream
类来实现
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipOutputStreamTester {
public static void main(String[] args) throws IOException {
ZipOutputStream out = new ZipOutputStream(
new BufferedOutputStream(
new FileOutputStream("test.zip")));
//使用ZipOutputStream作为输出流
for(int i=0; i
解压缩Zip文件使用ZipInputStream
类来实现
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipOutputStreamTester {
public static void main(String[] args) throws IOException {
System.out.println("Reading file!");
ZipInputStream in2 = new ZipInputStream(
new BufferedInputStream(
new FileInputStream("test.zip")));
//使用ZipInputStream来定义输入流
ZipEntry ze;
while((ze=in2.getNextEntry())!=null) //获取文件入口
{
System.out.println("Reading file"+ze.getName());
int x;
while((x=in2.read())!=-1)
System.out.write(x);
//将文件内容输出
System.out.println();
}
in2.close();
}
}
上面我们只是将压缩文件输出而已,我们更希望将压缩文件解压为一个一个的文件,下面我们来实现这一功能
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Unzip {
byte doc[] = null;
String Filename = null;
String UnZipPath = null;
public Unzip(String filename, String unZipPath) //构造函数初始化文件名和压缩路径
{
this.Filename = filename;
this.UnZipPath = unZipPath;
this.setUnZipPath(this.UnZipPath);
}
public Unzip(String filename)
{
this.Filename = new String(filename);
this.UnZipPath = null;
this.setUnZipPath(this.UnZipPath);
}
private void setUnZipPath(String unZipPath)//统一在路径名后面加上\\
{
if(unZipPath.endsWith("\\"))
this.UnZipPath=new String(unZipPath);
else
this.UnZipPath=new String(unZipPath+"\\");
}
public void doUnzip()
{
try
{
ZipInputStream zipis = new ZipInputStream(
new FileInputStream(Filename));
//用ZipInputStream定义输入流
ZipEntry fEntry = null;
//文件入口,可以参考前面的压缩文件操作
while((fEntry=zipis.getNextEntry())!=null)//压缩包中的文件是否解压缩完
{
if(fEntry.isDirectory()) //如果文件是一个路径,检查该文件是否存在,不存在就新建
checkFilePath(UnZipPath+fEntry.getName());
else
{
String fname = new String(UnZipPath+fEntry.getName()); //拼接路径名
try
{
FileOutputStream out = new FileOutputStream(fname);
doc=new byte[512]; //一次性读取512个字节,加快读取效率
int n;
while(((n=zipis.read(doc,0,512))!=-1)) //如果文件没有512字节,那么n就是字节个数
out.write(doc, 0, n);
out.close();
out=null;
doc=null;
}
catch(Exception ex)
{}
}
}
zipis.close();
}
catch(IOException ioe)
{
System.out.println(ioe);
}
}
private void checkFilePath(String dirName) { //检查文件是否存在,不存在就新建
// TODO Auto-generated method stub
File dir = new File(dirName);
if(!dir.exists())
dir.mkdir();
}
public static void main(String[] args) {
String zipFile=args[0];
String unZipPath = args[1]+"\\";
Unzip myZip=new Unzip(zipFile,unZipPath);
myZip.doUnzip();
}
}
ps:如果报错文件夹拒绝访问,可以去属性那里添加用户权限,百度找一下方法
对象序列化就是将对象的值保存到文件中,因为一个对象在程序的存活时间不长
使用的类为ObjectInputStream
和ObjectOutputStream
transient
和static
类型的变量Serializable
接口(Serializable接口只是一个标记,里边没有声明任何方法原型)下面一个程序实现将一个对象的值存入文件,再读取出来
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializableTester {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
// TODO Auto-generated method stub
Book book = new Book(10032,"ComupterNetworking");
//实例化一个对象,Book可以直接定义,在其他文件或同一文件下
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("book.dat"));
//使用ObjectOutputStream作为输出流
oos.writeObject(book);
oos.close();
book = null;
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("book.dat"));
//同上
book = (Book)ois.readObject();
//readObject可以得到对象的值,注意文件中保存对象的类型必须直接记录
ois.close();
System.out.println(book.id);
System.out.println(book.name);
}
}
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("book.dat"));
//使用ObjectOutputStream作为输出流
oos.writeObject(book);
oos.close();
book = null;
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("book.dat"));
//同上
book = (Book)ois.readObject();
//readObject可以得到对象的值,注意文件中保存对象的类型必须直接记录
ois.close();
System.out.println(book.id);
System.out.println(book.name);
}
}
参考
清华大学Java教程p67-p77