一、概念
在java.io包中操作文件内容的主要有两大类:字节流、字符流。两类都分为输入和输出操作,输入流基本方法是读,输出流基本方法是写。
二、字节流
字节流处理的基本单元为1个字节(byte),操作字节和字节数组,通常用来处理二进制数据。面向字节流的OutputStream和InputStream是一切的基础,两者均为抽象类,实际使用的是它们的一系列子类。
字节输出流
1.OutputStream
类定义:
public abstract class OutputStream implements Closeable, Flushable {}
//Closeable表示可关闭,Flushable表示刷新,清空内存中的数据
方法:
//将一个字节数据写入数据流
public abstract void write(byte b) throws IOException
//将一个byte数组写入数据流
public void write(byte b[]) throws IOException
//将指定byte数组中从偏移量off开始的len个字节写入数据流
public void write(byte b[], int off, int len) throws IOException
//刷新缓冲区
public void flush() throws IOException
//关闭输出流
public void close() throws IOException
要想使用此类及以上方法,必须通过子类实例化对象。
2.FileOutputStream
文件输出流,是向File或FileDescriptor输出数据的一个输出流。
构造方法:
1.创建一个文件输出流,向指定的File对象输出数据
public FileOutputStream(File file) throws FileNotFoundException
//字节写到文件的开始,输出会进行覆盖
public FileOutputStream(File file, boolean append) throws FileNotFoundException
//如果append设为true,字节将写到文件末尾
2.创建一个文件输出流,向指定名称的文件输出数据
public FileOutputStream(String name) throws FileNotFoundException
//输出会进行覆盖
public FileOutputStream(String name, boolean append) throws FileNotFoundException
//如果append设为true,字节将写到文件末尾
3.创建一个文件输出流,向指定的文件描述器输出数据,该文件描述符表示文件系统中一个实际文件的现有连接
public FileOutputStream(FileDescriptor fdObj)
3.ObjectOutputStream
对象输出流,将Java对象的原始数据类型和对象写入输出流,只有支持可序列化接口的对象才可以写入到输出流。
4.ByteArrayOutputStream
字节数组输出流,实现了一个以字节数组形式写入数据的输出流,缓冲区会随着数据的写入而自动扩大,可以用toByteArray()和toString()检索数据。
构造方法:
1.创建一个新的字节数组输出流
public ByteArrayOutputStream() {
this(32);
}
//缓冲区容量最初是32字节,如果需要,大小会增加
2.创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量
public ByteArrayOutputStream(int size)
5.PipedOutputStream
管道输出流,可以连接到管道输入流来创建通信管道,它是这个管道的发送端。一个线程通过管道输出流写入数据,另一个线程通过管道输入流读取数据,这样可实现两个线程之间的通信。不建议尝试从单个线程使用这两个管道流对象,因为它可能会造成线程死锁。
构造方法:
1.创建连接到指定管道输入流的管道输出流
public PipedOutputStream(PipedInputStream snk) throws IOException
2.创建一个管道输出流,该输出流尚未连接到管道输入流
public PipedOutputStream()
6.FilterOutputStream
其子类有DataOutputStream、BufferedOutputStream、PrintStream。
字节输入流
1.InputStream
类定义:
public abstract class InputStream implements Closeable
方法:
1.读取一个字节,返回0到255范围内的int字节值,读取到-1结束
public abstract int read() throws IOException;
2.将当前输入流中b.length个字节读入到byte数组中,实际读取的字节数作为整数返回
public int read(byte b[]) throws IOException
3.将当前输入流中len个字节数据读入一个字节数组中,从数组的off位置开始存放len长度的数据,实际读取的字节数作为整数返回
public int read(byte b[], int off, int len) throws IOException
4.从该输入流中跳过或忽略n字节
public long skip(long n) throws IOException
5.返回这个输入流中可读的字节数估计值,即可取得输入文件的大小
public int available() throws IOException
6.关闭输入流
public void close() throws IOException
要想使用此类及以上方法,必须通过子类实例化对象。
2.FileInputStream
文件输入流,从文件系统中的文件读取输入字节。
构造方法:
1.创建一个输入文件流,从指定的File对象读取数据
public FileInputStream(File file) throws FileNotFoundException
2.创建一个输入文件流,从指定名称的文件读取数据
public FileInputStream(String name) throws FileNotFoundException
3.创建一个输入文件流,从指定的文件描述器读取数据
public FileInputStream(FileDescriptor fdObj)
3.ObjectInputStream
对象输入流。
4.ByteArrayInputStream
字节数组输入流,把内存的一个缓冲区作为InputStream使用。
构造方法:
1.创建一个字节数组输入流,使用buf作为它的缓冲区数组,从缓冲区数组中读取数据
public ByteArrayInputStream(byte buf[])
2.创建一个字节数组输入流,从指定字节数组中读取数据
public ByteArrayInputStream(byte buf[], int offset, int length)
//offset表示读取缓冲区中第一个字节的偏移
//length表示从缓冲区读取的最大字符数
5.PipedInputStream
管道输入流,是一个通信管道的接收端。
构造方法:
1.创建连接到指定管道输出流的管道输入流
public PipedInputStream(PipedOutputStream src) throws IOException
public PipedInputStream(PipedOutputStream src, int pipeSize) throws IOException
//使用指定的管道大小作为管道的缓冲
2.创建一个管道输入流,该输出流尚未连接到管道输出流
public PipedInputStream()
public PipedInputStream(int pipeSize)
//使用指定的管道大小
6.SequenceInputStream
序列输入流,把几个输入连续地合并起来,它从一个有序的输入流集合开始,每个输入流依次被读取到文件的末尾,直到到达最后一个输入流的文件末尾。
构造方法:
1.参数中枚举生成运行时类型为输入流的对象,新创建一个序列输入流,通过读取由枚举产生的输入流来初始化它
public SequenceInputStream(Enumeration<? extends InputStream> e)
2.新创建一个序列输入流,按参数顺序读取输入流s1,s2来初始化它
public SequenceInputStream(InputStream s1, InputStream s2)
7.StringBufferInputStream
不推荐使用,此类不能将字符正确地转换为字节。从一个串创建一个流的最佳方法是采用StringReader类。
8.FilterInputStream
其子类有LineNumberInputStream(java8中已不建议使用)、DataInputStream、BufferedInputStream、PushbackInputStream。
三、字符流
字符流处理的基本单元为2个字节的Unicode字符,操作字符、字符数组或字符串,它通常用来处理文本数据。
java提供了Writer、Reader两个专门操作字符流的类,表示以Unicode字符为单位往流中写入或读取信息。
字符输出流
1.Writer
类定义:
public abstract class Writer implements Appendable, Closeable, Flushable
方法:
1.写一个字符
public void write(int c) throws IOException
2.写一个字符数组
public void write(char cbuf[]) throws IOException
abstract public void write(char cbuf[], int off, int len) throws IOException;
//从cbuf[]的off位置开始,写入字符数为len的字符数组
3.写入一个字符串
public void write(String str) throws IOException
public void write(String str, int off, int len) throws IOException
//从字符串str的off位置开始,写入的字符数为len
4.将指定的字符序列caq追加到该writer
public Writer append(CharSequence csq) throws IOException
//追加从指定序列的start位置开始,至end位置的字符序列
public Writer append(CharSequence csq, int start, int end) throws IOException
5.将指定字符追加到该writer
public Writer append(char c) throws IOException
6.强制性清空缓存
abstract public void flush() throws IOException;
7.关闭输出流
abstract public void close() throws IOException;
要想使用此类,必须通过子类实例化对象,使用子类。
2.FileWriter
如果是向文件中写入内容,应该使用FileWriter子类,与FileOutputStream对应。
构造方法:
1.构造给定File对象的FileWriter
public FileWriter(File file) throws IOException
//如果apped设为true,数据将写到文件的末尾而不是开始
public FileWriter(File file, boolean append) throws IOException
2.构造给定文件名的FileWriter
public FileWriter(String fileName) throws IOException
//如果append设为true,数据将写到文件的末尾
public FileWriter(String fileName, boolean append) throws IOException
3.构造与文件描述器相关联的FileWriter
public FileWriter(FileDescriptor fd)
3.BufferedWriter
拥有8192字符的缓冲区,使用BufferedWriter时,写入的数据不会先输出到目的地,而是先存储至缓冲区中,如果缓冲区满了,才会一次对目的地进行写出。
4.CharArrayWriter
与ByteArrayOutputStream对应。
5.PipedWriter
与PipedOutputStream对应。
6.FilterWriter
7.StringWriter
字符输入流
1.Reader
类定义:
public abstract class Reader implements Readable, Closeable
方法:
1.读取单个字符
public int read() throws IOException
2.将内容读入字符数组,返回读入的长度,如果到达输入流末端,返回-1
public int read(char cbuf[]) throws IOException
//len表示要读取的最大字符数
//将输入流中len个字符数据读入一个字符数组中,从数组的off位置开始存放len长度的数据
abstract public int read(char cbuf[], int off, int len) throws IOException
3.关闭输入流,并释放与之关联的任何系统资源
abstract public void close() throws IOException
要想使用此类,必须通过子类实例化对象,使用子类。
2.FileReader
如果要从文件中读取内容,可以直接使用FileReader子类,与FileInputStream对应。
构造方法:
1.创建一个新的FileReader,从指定的File对象读取数据
public FileReader(File file) throws FileNotFoundException
2.创建一个新的FileReader,从指定名称的文件中读取数据
public FileReader(String fileName) throws FileNotFoundException
3.创建一个新的FileReader,从指定的文件描述器读取数据
public FileReader(FileDescriptor fd)
3.BufferedReader
拥有8192字符的缓冲区,使用BufferedReader读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,之后若使用read()方法,会先从缓冲区中进行读取,如果缓冲区数据不足,才会从文件中读取。
4.CharArrayReader
与ByteArrayInputStream对应。
5.PipedReader
与PipedInputStream对应。
6.FilterReader
子类有PushbackReader。
7.StringReader
四、字节流与字符流转换
OutputStreamWriter和InputStreamReader是字节流与字符流的转换类。
OutputStreamWriter是Writer的子类,将输出的字符流转换成字节流。
InputStreamReader是Reader的子类,将输入的字节流转换成字符流。
1.OutputStreamWriter
OutputStreamWriter类是从字符流到字节流的桥梁,在OutputStreamWriter类中需要一个字节流的对象(OutputStream out)。OutputStreamWriter将多个字符写入到一个输出流,根据指定的字符编码将写入的字符编码成字节,实际负责编码的是StreamEncoder类,过程中必须使用指定的编码集。
类定义:
public class OutputStreamWriter extends Writer
构造方法:
1.可以通过名称指定支持的字符编码集
public OutputStreamWriter(OutputStream out, String charsetName) throws UnsupportedEncodingException
2.构造器中指定Charset类型
public OutputStreamWriter(OutputStream out, Charset cs)
3.接受平台的默认编码集
public OutputStreamWriter(OutputStream out)
4.使用指定charset encoder
public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
write()方法的每次调用都会在给定字符(或字符串)上调用编码转换器,在写入底层输出流之前,将在缓冲区中积累产生的字节。为了提高效率,可以考虑将OutputStreamWriter包装在一个BufferedWriter中,以避免频繁的转换。
例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
2.InputStreamReader
InputStreamReader类是从字节流到字符流的桥梁,在InputStreamReader类中需要一个字节流的对象,它使用的字符集可以通过名称指定,也可以明确Charset类型,也可以接受平台的默认字符集,与OutputStreamWriter类似。
类定义:
public class InputStreamReader extends Reader
构造方法:
public InputStreamReader(InputStream in, String charsetName)
public InputStreamReader(InputStream in, Charset cs)
public InputStreamReader(InputStream in)
每次调用InputStreamReader的read()方法,都可能导致从底层字节输入流中读取一个或多个字节,为了能有效地将字节转化为字符,可从底层输入流中读取更多字节,而不只是满足当前读取操作所需的字节。为了提高效率,可以考虑将InputStreamReader包装在一个BufferedReader中。
例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
五、例子
缓冲输入文件:
private String read(String filePath) {
try {
BufferedReader in = new BufferedReader(new FileReader(filePath));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null) {
sb.append(s + "\n");
}
in.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
String read = read(filePath);
Log.d(TAG, "zwm, read: \n" + read);
//IOTest.txt
12345
ABCDE
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, read:
12345
ABCDE
从内存输入:
private String read(String filePath) {
try {
BufferedReader in = new BufferedReader(new FileReader(filePath));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null) {
sb.append(s + "\n");
}
in.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
String read = read(filePath);
StringReader in = new StringReader(read);
int c;
try {
while((c = in.read()) != -1) {
Log.d(TAG, "zwm, c: " + c);
}
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
12345
ABCDE
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, c: 49
zwm, c: 50
zwm, c: 51
zwm, c: 52
zwm, c: 53
zwm, c: 10
zwm, c: 65
zwm, c: 66
zwm, c: 67
zwm, c: 68
zwm, c: 69
zwm, c: 10
格式化的内存输入:
private String read(String filePath) {
try {
BufferedReader in = new BufferedReader(new FileReader(filePath));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null) {
sb.append(s + "\n");
}
in.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
String read = read(filePath);
DataInputStream in = new DataInputStream(new ByteArrayInputStream(read.getBytes()));
try {
while(true) {
Log.d(TAG, "zwm, char: " + (char)in.readByte());
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "zwm, IOException");
}
//IOTest.txt
12345
ABCDE
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, char: 1
zwm, char: 2
zwm, char: 3
zwm, char: 4
zwm, char: 5
zwm, char:
zwm, char: A
zwm, char: B
zwm, char: C
zwm, char: D
zwm, char: E
zwm, char:
zwm, IOException
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
while(in.available() != 0) {
Log.d(TAG, "zwm, char: " + (char)in.readByte());
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "zwm, IOException");
}
//IOTest.txt
12345
ABCDE
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, char: 1
zwm, char: 2
zwm, char: 3
zwm, char: 4
zwm, char: 5
zwm, char:
zwm, char:
zwm, char: A
zwm, char: B
zwm, char: C
zwm, char: D
zwm, char: E
基本的文件输出:
private String read(String filePath) {
try {
BufferedReader in = new BufferedReader(new FileReader(filePath));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null) {
sb.append(s + "\n");
}
in.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
BufferedReader in = new BufferedReader(new StringReader(read(filePath)));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filePathOutput)));
int lineCount = 1;
String s;
while((s = in.readLine()) != null) {
out.println(lineCount++ + ": " + s);
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
12345
ABCDE
//IOTestOutput.txt
1:12345
2:ABCDE
private String read(String filePath) {
try {
BufferedReader in = new BufferedReader(new FileReader(filePath));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null) {
sb.append(s + "\n");
}
in.close();
return sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
BufferedReader in = new BufferedReader(new StringReader(read(filePath)));
PrintWriter out = new PrintWriter(filePathOutput);
int lineCount = 1;
String s;
while((s = in.readLine()) != null) {
out.println(lineCount++ + ": " + s);
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
12345
ABCDE
//IOTestOutput.txt
1:12345
2:ABCDE
读写随机访问文件:
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
RandomAccessFile rf = new RandomAccessFile(filePathOutput, "rw");
for(int i=0; i<7; i++) {
rf.writeDouble(i*1.414);
}
rf.writeUTF("Then end of the file");
rf.close();
RandomAccessFile rf2 = new RandomAccessFile(filePathOutput, "r");
for(int i=0; i<7; i++) {
Log.d(TAG, "zwm, readDouble: " + rf2.readDouble());
}
Log.d(TAG, "zwm, readUTF: " + rf2.readUTF());
rf2.close();
RandomAccessFile rf3 = new RandomAccessFile(filePathOutput, "rw");
rf3.seek(5*8);
rf3.writeDouble(47.0001);
rf3.close();
} catch (IOException e) {
e.printStackTrace();
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, readDouble: 0.0
zwm, readDouble: 1.414
zwm, readDouble: 2.828
zwm, readDouble: 4.242
zwm, readDouble: 5.656
zwm, readDouble: 7.069999999999999
zwm, readDouble: 8.484
zwm, readUTF: Then end of the file
读取二进制文件:
private byte[] read(String filePath) {
BufferedInputStream bf = null;
try {
bf = new BufferedInputStream(new FileInputStream(filePath));
byte[] data = new byte[bf.available()];
bf.read(data);
return data;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
byte[] readByte = read(filePath);
for(int i=0; i<readByte.length; i++) {
Log.d(TAG, "zwm, readByte: " + (char) readByte[i]);
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, readByte: 1
zwm, readByte: 2
zwm, readByte: 3
zwm, readByte: 4
zwm, readByte: 5
zwm, readByte:
zwm, readByte:
zwm, readByte: A
zwm, readByte: B
zwm, readByte: C
zwm, readByte: D
zwm, readByte: E
压缩:
Java I/O类库中的类支持读写压缩格式的数据流,最常用的压缩算法有Zip和GZIP。
压缩类的使用非常直观,直接将输出流封装成GZIPOutputStream或ZipOutputStream,并将输入流封装成GZIPInputStream或ZipInputStream即可。
用GZIP进行简单压缩:
File fileDir = getExternalCacheDir();
Log.d(TAG, "zwm, fileDir exists: " + fileDir.exists());
if(!fileDir.exists()) {
fileDir.mkdir();
Log.d(TAG, "zwm, fileDir exists: " + fileDir.exists());
}
String fileName = "IOTest.txt";
final String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
String fileNameGZ = "IOTest.gz";
String filePathGZ = fileDir + File.separator + fileNameGZ;
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
//写文件
//字符输入流
BufferedReader in = new BufferedReader(new FileReader(filePath));
//字节输出流
BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(filePathGZ)));
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
out.close();
in.close();
//读文件
//字节输入流转字符输入流
BufferedReader in2 = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(filePathGZ))));
String s;
while ((s = in2.readLine()) != null) {
Log.d(TAG, "zwm, output: " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Hello! My name is TomyZhang.
I an Android App developer.
I want to be a professional engineer.
I think my dream will come true soon.
Thank you~
//输出
zwm, fileDir exists: true
zwm, filePath: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest.txt, fileExist: true
zwm, output: Hello! My name is TomyZhang.
zwm, output: I an Android App developer.
zwm, output: I want to be a professional engineer.
zwm, output: I think my dream will come true soon.
zwm, output: Thank you~
用Zip进行多文件保存:
用Checksum类来计算和校验文件的校验和,一共两种Checksum类型:Adler32(快一些)和CRC32(慢一些)。
File fileDir = getExternalCacheDir();
Log.d(TAG, "zwm, fileDir exists: " + fileDir.exists());
if(!fileDir.exists()) {
fileDir.mkdir();
Log.d(TAG, "zwm, fileDir exists: " + fileDir.exists());
}
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileName2 = "IOTest2.txt";
String filePath2 = fileDir + File.separator + fileName2;
String fileName3 = "IOTest3.txt";
String filePath3 = fileDir + File.separator + fileName3;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
String fileNameGZ = "IOTest.gz";
String filePathGZ = fileDir + File.separator + fileNameGZ;
String fileNameZip = "IOTest.zip";
String filePathZip = fileDir + File.separator + fileNameZip;
boolean fileExist = new File(filePath).exists();
boolean file2Exist = new File(filePath2).exists();
boolean file3Exist = new File(filePath3).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
Log.d(TAG, "zwm, filePath2: " + filePath2 + ", file2Exist: " + file2Exist);
Log.d(TAG, "zwm, filePath3: " + filePath3 + ", file3Exist: " + file3Exist);
try {
//写文件
FileOutputStream f = new FileOutputStream(filePathZip);
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
ZipOutputStream zos = new ZipOutputStream(csum);
BufferedOutputStream out = new BufferedOutputStream(zos);
zos.setComment("A test of Java Zipping");
String[] args = {filePath, filePath2, filePath3};
for (String arg : args) {
Log.d(TAG, "zwm, zip: " + arg);
BufferedReader in = new BufferedReader(new FileReader(arg));
zos.putNextEntry(new ZipEntry(arg));
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
in.close();
out.flush();
}
out.close();
//读文件,方法1
FileInputStream fi = new FileInputStream(filePathZip);
CheckedInputStream csumi = new CheckedInputStream(fi, new Adler32());
ZipInputStream in2 = new ZipInputStream(csumi);
BufferedReader br = new BufferedReader(new InputStreamReader(in2));
ZipEntry ze;
while ((ze = in2.getNextEntry()) != null) {
Log.d(TAG, "zwm, Reading file: " + ze);
int x;
String s;
while ((s = br.readLine()) != null) {
Log.d(TAG, "zwm, output: " + s);
}
}
br.close();
//读文件,方法2
ZipFile zf = new ZipFile(filePathZip);
Enumeration e = zf.entries();
while (e.hasMoreElements()) {
ZipEntry ze2 = (ZipEntry) e.nextElement();
// 同上
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "zwm, IOException");
}
//IOTest.txt
Hello! My name is TomyZhang.
//IOTest2.txt
I an Android App developer.
//IOTest3.txt
I want to be a professional engineer.
//输出
zwm, fileDir exists: true
zwm, filePath: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest.txt, fileExist: true
zwm, filePath2: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest2.txt, file2Exist: true
zwm, filePath3: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest3.txt, file3Exist: true
zwm, zip: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest.txt
zwm, zip: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest2.txt
zwm, zip: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest3.txt
zwm, Reading file: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest.txt
zwm, output: Hello! My name is TomyZhang.
zwm, Reading file: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest2.txt
zwm, output: I an Android App developer.
zwm, Reading file: /storage/emulated/0/Android/data/com.tomorrow.bustest/cache/IOTest3.txt
zwm, output: I want to be a professional engineer.