您的位置:首页 > 职场人生

黑马程序员----IO流

2015-06-15 21:48 507 查看
——- android培训java培训、期待与您交流! ———-

File类:文件和目录路径名的抽象表示形式。

File类在整个IO包中与文件本身有关的操作类,文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。这些限制统称为访问权限。文件系统可以对一个对象设置多个访问权限。File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变。

路径名字符串与抽象路径名之间的转换与系统有关。将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符 隔开。默认名称分隔符由系统属性 file.separator 定义,可通过此类的公共静态字段 separator 和 separatorChar 使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。不同操作系统路径分割符不同,注意兼容性

构造方法:

File(File parent, String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(String pathname)  通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(URI uri)  通过将给定的 file: /URI 转换为一个抽象路径名来创建一个新的 File 实例,
URI uri = new URI("file:/C:/OOXX.txt");
。


常用方法:

/**创建*/
boolean mkdir() 创建此抽象路径名指定的目录。(父目录不存在时不能直接创建子目录)
boolean mkdirs()创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 (会自动创建子目录所必须的父目录)
boolean createNewFile()当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
static File createTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
static File createTempFile(String prefix, String suffix, File directory) 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
/**删除*/
boolean delete()删除此抽象路径名表示的文件或目录。(再次之前需判断文件是否存在,如果是目录,期内不能有子元素,此时可考虑递归删除)
void deleteOnExit() 在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
/**判断*/
boolean exists():判断对象对应的文件或目录是否存在;
boolean canWrite():判断对象对应文件或目录是否可写;
boolean canRead():判断对象对应文件或目录是否可读;
boolean  isFile():判断对象是文件,不是目录;
boolean isDirectory()  判断对象的文件是否是一个目录;
boolean isAbsolute() 判断对象对应文件或目录是否为绝对路径名
boolean isHidden() 判断此路径名指定的文件是否是一个隐藏文件。
long lastModified() 返回文件最后一次被修改的时间。
long length() 返回文件内容的长度。
String getName():返回文件名或路径名(若是路径,返回最后一级子路径名)
String getPath():返回对象对应的路径名
File  getAbsoluteFile():返回绝对路径
String getAbsolutePath():返回对象对应的绝对路径
String getParent():返回文件目录的上一级目录名
/**操作*/
boolean renameTo(File newName):重命名此File对象对应的文件或目录,若重命名成功返回true
String[] list():列出File对象的所有子文件名和路径名。
File[] listFiles():列出File对象的所有子文件和路径。
static File[] listRoots():列出系统所有的根路径;


实例代码:

从控制台就收 一个字符串,打印其内及其所有子目录内的java文件的绝对路径名:

import java.io.File;
import java.util.Scanner;

public class FindJavaFile {

public static void main(String[] args) {
/**接受控制台传来的文字*/
System.out.println("请输入文件路径,用/取代\\");
Scanner in = new Scanner(System.in);
String name = in.next();;
File f= new File(name);
/**定义一个方法来完成,以方便递归*/
fore(f);

}

public static void fore(File f){
/**验证f为目录,不然应当报错,此处省略,直接将f当作目录*/
File[] files = f.listFiles();
for (File uf : files) {
//如果uf为目录,递归
if(uf.isDirectory()){
fore(uf);
}else {
//不为目录判断uf的拓展名
if(uf.getName().endsWith(".java")){
System.out.println(uf.getAbsolutePath());
}
}
}

}

}
输出结果:
请输入文件路径,用/取代\
C:/Users/Acer/workspace/readForExam/src/xia/wt
C:\Users\Acer\workspace\readForExam\src\xia\wt\AutoCloseableDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\Base.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\Car.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\CarBrand.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\collectionDemo\ArrayListDemo1.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\collectionDemo\Demo1.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\collectionDemo\PropertiesDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\FindJavaFile.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\ioDemo\FileDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\LocalInnerClass.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\MyList.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\notifyDemo\Demo1.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\Outer.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\PrimeNumber.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\ReceiveFiel.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\SaveCar.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\SendFile.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\StringDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\DeadlockDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\Demo1.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\ExThreadDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\ReentrantLockDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\ThreadDemo1.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\threadDemo\ThreadDemo2.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\ThreadDemo.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\UnnameInnerClass.java
C:\Users\Acer\workspace\readForExam\src\xia\wt\Vendor.java


String[] list(FilenameFilter filter) 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。

FilenameFilter(文件过滤器)该接口里包含accept(File dir,String name)方法,该方法依次对指定File的所有子目录,子文件夹进行迭代。

dir - 被找到的文件所在的目录。

name - 文件的名称。

当且仅当该名称应该包含在文件列表中时返回 true;否则返回 false.

RandomAccessFile

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。

类支持直接输出输入各种数据类型;

可以跳到文件的任意位置读取或写入信息;
1154d

只能操作文件,不能操作其他的IO设备,可用于断点下载,数据库存储;

public RandomAccessFile(File file,String mode)throws FileNotFoundException

mode 参数指定用以打开文件的访问模式。允许的值及其含意为:

“r” 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。

“rw” 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。

“rws” 打开以便读取和写入,对于 “rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。

“rwd” 打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。

示例代码:

//在一个utf-8编码的文件末尾田间一行文字
public class RandomAccessFileDemo {

public static void main(String[] args) throws IOException {
File f = new File("C:/Users/Acer/workspace/readForExam/src/txt.txt");
RandomAccessFile raf = new RandomAccessFile(f, "rw");
raf.seek(raf.length());
raf.writeUTF("这是新加的一行文字");
raf.close();
}

}


====================================

:数据写入程序可以使一段一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。在程序中所有的数据都是以流的方法进行传输和保存的。

所有流都继承于以下四种抽象流类型的某一种:

InputStream:此抽象类是表示字节输入流的所有类的超类。 需要定义 InputStream 子类的应用程序必须总是提供返回下一个输入字节的方法。

OutputStream:此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法。

Writer:写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

Reader:用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

字节流与字符流仅仅是操作数据的单位不同。一般来说处理字符或字符串时使用字符流,处理字节或二进制对象时应使用字节流。

字节流和字符流的区别

字节流和字符流在使用上的代码结构都是非常类似的,但是其内部本身也是有区别的,因为在进行字符流操作的时候会使用到缓冲区,而字节流操作的时候是不会使用到缓冲区的。

在输出的时候,OutputStream类即使最后没有关闭内容也可以输出。但是如果是Writer的话,则如果不关闭,最后一条内容是无法输出的,因为所有的内容都是保存在了缓冲区之中,每当调用了close()方法就意味着清空缓冲区了。那么可以证明字符流确实使用了缓冲区:

字节流:程序 → 文件

字符流:程序 → 缓冲区 → 文件

如果现在字符流即使不关闭也可以完成输出的话,则必须强制性清空缓冲区:

方法:public void flush() throws IOException

两者相比,肯定使用字节流更加的方便,而且在程序中像图片、MP3等都是采用字节的方式的保存,那么肯定字节流会比字符流使用的更广泛。

但是需要说明的是,如果要是想操作中文的话,字符流肯定是最好使的。

相互转换:

OutputStreamWriter:把字节输出流对象转成字符输出流对象
InputStreamReader:把字节输入流对象转成字符输入流对象
FileWriter和FileReader分别是OutputStreamWriter和InputStreamReader的直接子类,而不是Writer和Reader的直接子类,区别于FileInputStream 和InputStream。
注:无论使用字节流还是字符流实际上在内存中最终都是通过字节的形式来操作流的。


流的工作流程

File类本身是与文件操作有关,但是如果要想操作内容则必须使用字节流或字符流完成,但是不管是使用何种的输入输出流,其基本的操作原理是一样的(以文件流为准):

1.使用File类找到一个文件对象,得到IO操作的源或目标

2.通过字节流或字符流的子类创建对象,得到IO操作的通道

3.进行读或写的操作,IO操作

4.关闭输入/输出,(注意节约资源,关掉)

由于流的操作属于资源操作,所以在操作的最后一定要关闭以释放资源

常用方法:

InputStream

void flush() throws IOException:清空缓冲区
abstract void close() throws IOException:关闭输出流
void write(int c) throws IOException:将一个字节写到输出流中。
void write(byte[] b) throws IOException:将一个byte数组写出。
void write(byte[] b,int off,int len) throws IOException:将字节数组从off位置开始,长度为len的字节写入到输出流中。
以其子类FileOutputStream来实例化OutputStream对象
FileOutputStream(File/String file)  throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File/String file, boolean append)   throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流


OutputStream

void flush() throws IOException:清空缓冲区
abstract void close() throws IOException:关闭输出流
void write(int c) throws IOException:将一个字节写到输出流中。
void write(byte[] b) throws IOException:将一个byte数组写出。
void write(byte[] b,int off,int len) throws IOException:将字节数组从off位置开始,长度为len的字节写入到输出流中。
以其子类FileOutputStream来实例化OutputStream对象
FileOutputStream(File/String file)  throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File/String file, boolean append)   throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流


Reader

abstract void close() throws IOException:关闭流
int read() throws IOException:从输入流中读取单个字符。
int read(char[] cbuf) throws IOException:从输入流中读取最多c.length个字节的数据,并将其存储在字符数组c中,返回实际读取的字节。
直到read(char[] c)方法返回-1表示输入流的结束。
char[] cBuff = new char[1024];//动态声明数组,长度
read(cBuff ) !=-1   read(cBuff )  >0
以其子类FileReader来实例化Reader对象
FileReader(File/String file) throws FileNotFoundException 创建一个向指定对象的文件输入流


Writer

abstract void flush() throws IOException:清空缓存
abstract void close() throws IOException:关闭流
void write(char[] cbuf):将字符数组中的数据输入到输出流中。
void write(char[] cbuf,int off,int len):将字符数组从off位置开始,长度为len的字节输入到输出流中。
void  write(String str):将str字符串所有字符输出到指定的输出流中。
void write(String str,int off, int len):将str字符串里从off位置开始,长度为len的字符输出到指定的输出流中。
以其子类FileWriter来实例化Writer对象
FileWriter(File/String file, boolean append) throws FileNotFoundException 创建一个向指定对象的文件输出流,append表示是否追加。默认是false


自动关闭资源

http://blog.csdn.net/qq775857005/article/details/46386309

常用流

内存操作流

ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

CharArrayReader此类实现一个可用作字符输入流的字符缓冲区。

CharArrayWriter此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用toCharArray() 和 toString() 获取数据。

在此类上调用 close() 无效,并且在关闭该流后可以调用此类中的各个方法,而不会产生任何 IOException。

//将一个字符串储存在内存流中,然后取出
public class ByteArrayDemo {
public static void main(String[] args) throws Exception {
String info = "helloworld";
InputStream input = new     ByteArrayInputStream(info.getBytes());
OutputStream output = new ByteArrayOutputStream();
int temp = 0;
while ((temp = input.read()) != -1) {
output.write(Character.toUpperCase((char) temp));
}
String str = output.toString(); // 取出内容
input.close() ;//关闭无用
output.close() ;//无效
System.out.println(str) ;
}
}


打印流:

PrintWriter和PrintStream都属于输出流,分别针对字符和字节。

PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println 方法,或写入一个换行符或字节 (‘\n’)。 PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。

PrintWriter 向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。 此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用 checkError() 是否出现错误。

Java5后,PrintStream类多了printf()方法用于格式化输出操作。但是格式化输出的时候必须指定输出数据的类型:

PrintStream printf(Locale l, String format, Object... args) 使用指定格式字符串和参数将格式化的字符串写入此输出流的便捷方法。
PrintStream printf(String format, Object... args) 使用指定格式字符串和参数将格式化的字符串写入此输出流的便捷方法。


字符 描述

%s 表示内容是字符串

%d 表示内容是整数

%f 表示内容是小数

%c 表示内容是字符

print()里的参数不能为空;println()可以 PrintWriter和PrintStream输出操作不抛出异常

PrintStream调用println方法有自动flush功能;

实例代码:

讲一个文本文件转为utf-8编码

public class PrintWriteToFile {
public static void main(String[] args) throws IOException {
File f = new File("txt1.txt");
f.createNewFile();
try(FileReader fr = new FileReader("txt.txt");
PrintWriter pw = new PrintWriter(f,"UTF-8");
){
char[] chars = new char[1024];
int i ;
while((i= fr.read(chars))!=-1){
pw.print(new String(chars,0,i));
}
}catch (Exception e) {
}
}
}


管道流

又称为线程通讯流,主要作用是可以进行两个线程之间的通讯:

PipedOutputStream:管道输出流

PipedInputStream:管道输入流

PipedOutputStream中有方法:

void connect(PipedInputStream pis) throws IOException:用于连接管道

PipedInputStream中有方法:

void connect(PipedOutputStream pos) throws IOException:用于连接管道

//从一个线程向另一个线程发送一段文字
package xia.wt.ioDemo;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedStream {
public static void main(String[] args) {
Send s = new Send();
Receive r = new Receive();
try {
//将两个线程的输入、输出流连接起来
s.getOut().connect(r.getIn());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s.start();
r.start();
}

}

//发送线程
class Send extends Thread{
//建立管道输出流,并暴露给外部,以方便和输入流对接
private PipedOutputStream out = new PipedOutputStream();
public PipedOutputStream getOut(){
return out;
}

@Override
public void run() {
String s = "此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置";
//输出并关闭流,此处严格的关闭
byte[] bs =s.getBytes();
try {
out.write(bs);
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

//接受线程
class Receive extends Thread{
//创建管道输入流,并暴露给外部
private PipedInputStream  in = new PipedInputStream();
public PipedInputStream getIn () {
return in;
}
//接受数据并关闭流
@Override
public void run() {
byte[] bs = new byte[1024];
int i;
try {
while((i=in.read(bs))!=-1){
System.out.println(new String(bs, 0, i));
}
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


处理流

对已存在的流的连接和封装,通过封装流的功能调用实现数据读写。处理流的构造方法总会带一个其他流对象作参数,一个流对象经过其他流的多次包装,称为流的链接。

当使用处理流的时候,在关闭输入/输出资源时。只需要关闭上层流即可。因为当关闭上层流的时候系统会默认去关闭被处理的节点流。

缓冲流

缓冲流属于一种处理流,对读写的数据提供了缓冲的功能,提高了读写效率,同时增加了一些新的方法。

BufferedReader(Reader in)

BufferedReader(Reader in,int sz)//sz表示自定义缓冲区大小

BufferedWriter(Writer out)

BufferedWriter(Writer out,int sz)

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int sz)

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int sz)

BufferedReader提供readLine方法用于读取一行字符串。
BufferedWriter提供了newLine方法用于写入一个行分隔符。等价于//.writer("\r\n");
对于输出的缓冲流,写出的数据会先在内存中缓冲,使用flush方法将会使内存中的数据立刻写出。


数据操作流

DataInputStream 和 DataOutputStream分别继承于InputStream 和 OutputStream,属于处理流,需要分别“套接”在InputStream 和OutputStream类型的节点流上。

DataInputStream 和DataOutputStream提供了可以存储Java原始类型数据(如int,boolean等)的方法。

合并流

SequenceInputStream:

将两个文件的内容合并成一个文件

该类提供的方法:

SequenceInputStream(InputStream s1, InputStream s2) :根据两个字节输入流对象来创建合并流对象。

System里的流

Java的标准输入输出,分别通过System.in和System.out表示,默认情况下,他们分别表示键盘和屏幕。也就是说键盘输入,屏幕显示输出。

System类里面有三个重定向标准输入/输出的方法:

static void setErr(PrintStream err):重定向“标准”错误输出流”

static void setIn(InputStream in):重定向“标准”输入流”

static void setOut(PrintStream out):重定向“标准”输出流”

对象操作流

http://blog.csdn.net/qq775857005/article/details/46416595

压缩流

压缩流的操作类都处于java.uti.zip中;

在java中要实现zip的压缩需要使用包中的ZipFile,ZipOutputStream,ZipInputStream,ZipEntry类。

jar和文件格式的压缩输入,输出流

jar压缩输出流:JarOutputStream

jar压缩输入流:JarInputStream

jar文件:JARFile

jar实体:JarEntry

gzip用于unix系统的文件压缩,Linux中经常使用到*.gz就是gzip格式。

GZIP压缩输出流:GZIPOutputStream

GZIP压缩输入流:GZIPInputStream

ZipEntry & ZipOutputStream

ZipEntry用于表示 ZIP 文件条目,也就是压缩文件中的每一个子文件。

ZipEntry(String name)使用指定ZipEntry名称创建新的 ZipEntry对象。

boolean isDirectory()判断该ZipEntry是不是目录。

ZipOutputStream用于完成一个文件或文件夹的压缩。

ZipOutputStream(OutputStream out) 创建新的 ZIP 输出流

void putNextEntry(ZipEntry e) 设置ZipEntry对象

void setComment(String comment) 设置 ZIP 文件注释。

ZipFile & ZipInputStream

Java里每个压缩文件用ZipFile表示,可使用ZipFile压缩后的文件名称找到每一个压缩文件中的ZipEntry并将其解压缩操作。

ZipFile(File file):获得ZipFile对象

ZipEntry getEntry(String name):根据名字获得对应ZipEntry对象

InputStream getInputStream(ZipEntry entry):

String getName():获得压缩文件的路径名

ZipInputStream

ZipInputStream(InputStream in)

ZipEntry getNextEntry() 获得下一个ZipEntry

实例代码:

压缩一个有子目录的文件夹

public class ZipStream {

public static void main(String[] args) {
File src = new File("C:/Users/Acer/workspace/readForExam/src");
File zip = new File("C:/Users/Acer/Desktop/src.zip");
//创建源文件夹及目标压缩文件
zip(src,zip);
}

public static void zip(File src,File zip){
//准备输出流。作为形参传递,以方便重复使用
try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip));)
{
reZip(zos, src);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//定义一个新的方法翻遍递归
public static void reZip(ZipOutputStream zos,File f){
//判断目标是文件还是文件夹,文件则压缩,文件夹则递归
if(f.isFile()){
//获得目标文件的目录结构,是的压缩后的文件目录不至于混乱
String name = f.getPath().substring(f.getAbsolutePath().indexOf("\\"));
//准备ZipEntry并开始写入文件
ZipEntry en = new ZipEntry(name);
try(FileInputStream in  =new FileInputStream(f))
{   zos.putNextEntry(en);
int i =0;
byte[] bs = new byte[1024];
while((i=in.read(bs))!=-1){
zos.write(bs, 0, i);
}

}catch (Exception e) {
System.out.println("yichang");
}
}else {
//目标是文件夹则递归
File[] fs =f.listFiles();
for (File file : fs) {
System.out.println("----------"+file.getPath());
reZip(zos, file);
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java-se IO