在变量、数组和对对象中存储的数据是暂时的,程序结束后它们会自动消失。为了能够永久地保存程序创建的数据,需要将其保存在磁盘文件中,这样就可以在其他程序中使用它们。Java的I/O技术可以将数据保存到文本文件,二进制文件甚至是ZIP压缩文件中,以达到永久性保存数据的要求。
流是一组有序的数据序列,根据操作的类型,可分为输入流和输出流。I/O(Input/Output,输入输出) 流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流通常与磁盘文件存取有关,但是程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口等。 Java由数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据。源可以是文件、网络、压缩包或其他数据源。 输出流的指向是数据要到达的目的地,程序通过向输出流中写入数据把信息传递到目的地。输出流的目标可以是文件、网络、压缩包或其他数据源。
Java语言定义了许多类专门负责各种方式的输入输出,这些类都被放在java.io包中。其中,所有的输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。
InputStream类是字节输入流的抽象类,是所有字节输入流的父类。InputStream类的具体层次结构如下: 该类中的所有方法遇到错误时都会引发IOException异常。 方法说明:
(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。 (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的 。 (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。 (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用。 (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取 。 (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭。说明: 并不是所有的InputStream类的子类都支持InputStream中定义的所有方法,如skip()、mark()、reset()等方法只对某些子类有用。
Java中的字符是Unicode编码,是双字节的。InputStream是用来处理字节的,并不适合处理字符文本。Java为字符文本的输入专门提供了一套单独的类Reader,但Reader类并不是InputStream类替换者,只是在处理字符串时简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。 Reader类的具体层次结构如下:
OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。OutputStream类的具体层次结构如下: OutputStream类中的所有的方法均返回void,在遇到错误时会引发IOException异常。方法说明:
1. public void write(byte b[ ]):将参数b中的字节写到输出流。 2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。 3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。 4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。 5. public void close( ) : 关闭输出流并释放与流相关的系统资源。Write类是字符输出流的抽象类,所有的字符输出类的类的实现都是它的子类。Writer类的层次结构如下: Java流的分类 按流向分: 输入流: 程序可以从中读取数据的流。 输出流: 程序能向其中写入数据的流。 按数据传输单位分: 字节流: 以字节为单位传输数据的流 字符流: 以字符为单位传输数据的流 按功能分: 节点流: 用于直接操作目标设备的流 处理流: 是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。
File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件的读写权限等。数据流可以将数据写入到文件中,文件也是数据流最常用的数据媒体。
可以使用File类创建一个文件对象。 通常使用以下3种构造方法来创建文件对象。
(1)File(String pathname):该构造方法通过将给定路径名字符串转换为抽象路径名来创建一个新File实例. File file=new File(“d:/1.txt”) (2)File(String parent,String child):该构造方法根据定义的父路径和子路径字符串(包含文件名)创建一个新的实例. (3)File(File f,String child):该构造方法根据parent抽象路径名和child路径名字符串创建一个新File实例.说明: 对于Microsoft Windows平台,包含盘符的路径名前缀由驱动器号和一个“:”组成。如果路径名是绝对路径,还可能后跟“\”。 代码示例: 在项目中创建类FileTest,在主方法中判断E盘的myword文件夹是否存在word.txt文件,如果该文件存在起将其删除,不存在则创建该文件。
import java.io.File; public class FileTest { public static void main(String[] args) { // TODO Auto-generated method stub //创建文件对象 File file=new File("word.txt"); //如果文件存在 if (file.exists()) { //将文件删除 file.delete(); System.out.println("文件已被删除!"); //如果文件不存在 }else { try { //创建文件 file.createNewFile(); System.out.println("文件已被创建!"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } }File类提供了很多方法用于获取一些文本信息,其中常用的方法如下:
方法说明getName()获取文件的名称canRead()判断文件是否是可读的canWrite()判断文件是否可被写入exists()判断文件是否存在length()获取文件的长度(以字节为单位)getAbsolutePath()获取文件的绝对路径getParent()获取文件的父路径isFile()判断文件是否存在isDirectory()判断文件是否是一个目录isHidden()判断文件是否是隐藏文件lastModified()获取文件最后修改时间代码示例: 获取当前文件夹下的word.txt文件的文件名,文件长度并判断该文件是否是隐藏文件。
import java.io.File; public class FileGetInfoMethod { public static void main(String[] args) { // TODO Auto-generated method stub // 创建文件对象 File file = new File("word.txt"); if (file.exists()) { // 获取文件名称 String name = file.getName(); // 获取文件长度 long length = file.length(); // 判断文件是否是隐藏文件 boolean hidden = file.isHidden(); System.out.println("文件名称:" + name); System.out.println("文件长度:" + length); System.out.println("该文件是否是隐藏文件:" + hidden); } else { System.out.println("该文件不存在!"); } } }程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭时,这些数据将消失,如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到中。
Filelnputstream类与Fileoutputstream都用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FilelnputStream类,该类继承自 InputStream类。 FileOutputStream类与FilelnputStream对应,提供了基本的文件写入能力。 FileOutputStream类是 OutputStream类的子类。 FilelnputStream类常用的构造方法如下:
FilelnputStream(String name) FilelnputStream(File file)第一个构造方法使用给定的文件名name创建一个 FilelnputStream对象,第二个构造方法使用File对象创建FilelnputStream对象。第一个种造方法比较简单,但第二个构造方法允许在把文件连接输入流之前对文件进一步分析。 FileOutputStream类有与FilelnputStream类相同的参数构造方法,创建一个 FileOutputStream对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。 代码示例: 使用FileOutputStream类向文件word.xt写入信息,然后通过FilelnputStream类将文件中的数据读取到控制台上。
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; //文件输入/输出流 public class FileInputOutputStreamTest { public static void main(String[] args) { // TODO Auto-generated method stub File file = new File("word.txt"); try { // 创建FileOutputStream对象 FileOutputStream fileOutputStream = new FileOutputStream(file); // 创建byte[]型数组 byte[] buy = "我有一只小毛驴,我从来也不骑。".getBytes(); // 将数组中的文件写入到文件中 fileOutputStream.write(buy); // 将流关闭 fileOutputStream.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } try { // 创建FileInputStream对象 FileInputStream fileInputStream = new FileInputStream(file); // 创建bute[]型数组 byte[] byt = new byte[1024]; // 从文件中读取信息 int length = fileInputStream.read(byt); // 将文件中的信息输出 String string = new String(byt, 0, length); System.out.println("文件中的信息:" + string); // 关闭流 fileInputStream.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }说明: 虽然Java在程序j结束时自动关闭所有打开的流,但是当使用完流后,显式地关闭所有打开的流仍是一个好习惯。一个被打开的流有可能会用尽系统资源,这取决于平台和实现。如果没有将打开的流关闭,当另一个程序试图打开另一个流时,可能会得不到需要的资源。
使用FileOutputStream类向文件中写入数据与使用FilelnputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用两个字节,如果使用字节流,读取不好可能会出现码现象,此时采用字符流Reader或Writer类即可避免这种现象。 FileReader和FileWriter字符流对应了FilelnputStream和 FileOutputStream类,FileReader流顺序地读取文件,只要不关闭流,每次调用read() 方法就顺序地读取源中其余的内容,直到源的末尾或流被关闭。 代码示例: 创建Swing留体,单击窗体中的“写入文件”按钮实现将文本框中的数据写入到磁盘文件中,单击“读取文件”按钮,系统将磁文件中的信息显示在文本框中。
import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class Ftest extends JFrame { // 创建类,继承JFrame类 private JScrollPane scrollPane; private static final long serialVersionUID = 1L; private JPanel jContentPane = null; // 创建面板对象 private JTextArea jTextArea = null; // 创建文本域对象 private JPanel controlPanel = null; // 创建面板对象 private JButton openButton = null; // 创建按钮对象 private JButton closeButton = null; // 创建按钮对象 private JTextArea getJTextArea() { if (jTextArea == null) { jTextArea = new JTextArea(); } return jTextArea; } private JPanel getControlPanel() { if (controlPanel == null) { FlowLayout flowLayout = new FlowLayout(); flowLayout.setVgap(1); controlPanel = new JPanel(); controlPanel.setLayout(flowLayout); controlPanel.add(getOpenButton(), null); controlPanel.add(getCloseButton(), null); } return controlPanel; } private JButton getOpenButton() { if (openButton == null) { openButton = new JButton(); openButton.setText("写入文件"); // 修改按钮的提示信息 openButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 按钮的单击事件 File file = new File("word.txt"); // 创建文件对象 try { FileWriter out = new FileWriter(file); // 创建FileWriter对象 String s = jTextArea.getText(); // 获取文本域中的文本 out.write(s); // 将信息写入磁盘文件 out.close(); // 将流关闭 } catch (Exception e1) { e1.printStackTrace(); } } }); } return openButton; } private JButton getCloseButton() { if (closeButton == null) { closeButton = new JButton(); closeButton.setText("读取文件"); // 修改按钮的提示信息 closeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 按钮的单击事件 File file = new File("word.txt"); // 创建文件对象 try { FileReader in = new FileReader(file); // 创建FileReader对象 char byt[] = new char[1024]; // 创建char型数组 int len = in.read(byt); // 将字节读入数组 jTextArea.setText(new String(byt, 0, len)); // 设置文本域的显示信息 in.close(); // 关闭流 } catch (Exception e1) { e1.printStackTrace(); } } }); } return closeButton; } public Ftest() { super(); initialize(); } public void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(new BorderLayout()); jContentPane.add(getScrollPane(), BorderLayout.CENTER); jContentPane.add(getControlPanel(), BorderLayout.SOUTH); } return jContentPane; } public static void main(String[] args) { // main主方法 Ftest thisClass = new Ftest(); // 创建本类对象 thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); thisClass.setVisible(true); // 设置该窗体未显示状态 } protected JScrollPane getScrollPane() { if (scrollPane == null) { scrollPane = new JScrollPane(); scrollPane.setViewportView(getJTextArea()); } return scrollPane; } }缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()、mark()和reset() 方法都成为可能。
BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。 BufferedInputStream类有两个构造方法:
BufferedInputStream(InputStream in) BufferedInputStream(InputStream in,int size)第一种形式的构造方法创建一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象位于InputStream类对象之前。 字节数据读取文件的过程: 文件——InputStream——BufferedInputStream——目的地 使用BufferedOutputStream输出信息和用OutputStream输出的信息完全一样,只不过BufferedOutputStream有一个**flush()**方法用来将缓存区的数据强制输出完。BufferedOutputStream类的两个构造方法:
BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out,int size)第一种形式的构造方法创建一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。 注意: flush() 方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush() 方法只对使用缓存区的OutputStream类的子类有效,当调用close() 方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件中。
BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。 字符数据读取文件的过程: 字符数据——BufferedWriter——OutputStreamWriter——OutputStream——文件 BufferedReader类的常用的方法:
read():读取单个字符. readLine():读取一个文本行,并将其返回为字符串。若无数据可读,则返回null.BufferedWriter类中的方法都返回void,常用的方法:
write(String str,int offset,int len):写入字符串的某一部分. flush():刷新该流的缓存. newLine():写入下一行分割符.在使用BufferedWriter类中的write()方法时,数据并没有立刻被写入至输出流,而是首先进入缓存区中。如果想立刻将缓存区的数据写入输出流,一定要调用flush()方法。 代码示例: 本实例向指定的磁盘文件中写入数据,并通过BufferedReader类将文件中的信息分行显示。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; public class Student { public static void main(String[] args) { // TODO Auto-generated method stub // 定义字符串数组 String[] contentStrings = { "好久不见", "最近还好吗", "常联系" }; // 创建文件对象 File file = new File("word.txt"); try { // 创建FileWriter类对象 FileWriter fileWriter = new FileWriter(file); // 创建BufferedWriter类对象 BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); // 循环遍历数组 for (int i = 0; i < contentStrings.length; i++) { // 将字符串数组中的元素写入到磁盘中 bufferedWriter.write(contentStrings[i]); // 将数组中的单个元素以单行的形式写入文件 bufferedWriter.newLine(); } // 将BufferedWriter流关闭 bufferedWriter.close(); // 将FileWriter流关闭 fileWriter.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } try { // 创建FileReader类对象 FileReader fileReader = new FileReader(file); // 创建BufferedReader类对象 BufferedReader bufferedReader = new BufferedReader(fileReader); // 创建字符串对象 String string = null; // 声明int型变量 int i = 0; // 如果文件的文本行数不为null,则进入循环 while ((string = bufferedReader.readLine()) != null) { // 将变量做自增运算 i++; System.out.println("第" + i + "行:" + string); } // 将BufferedReader流关闭 bufferedReader.close(); // 将FileReader流关闭 fileReader.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }数据输入输出流( DatalnputStream类与 DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是哪种字节。 DatalnputStream类与DataOutputStream类的构造方法如下:
DatalnputStream(InputStream in):使用指定的基础**InputStream**创建一个**DatalnputStream**. DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流.DataOutputStream类提供了如下3种写入字符串的方法:
writeBytes(String s) writeChars(String s) writeUTF(String s)由于Java中的字符是 Unicode编码,是双字节的。 writeBytes :只是将字符串中的每一个字符的低节内容写入目标设备中; writeChars :将字符串中的每一个字符的两个字节的内容都写到目标没备中;writeUTF: 将字符串按照UTF编码后的字节长度写入目标设备,然后オ是每一个字节的UTF编码。 DatalnputStream类只提供了一个 readUTF() 方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。 DataOutputStream类中只有 writeUTF() 方法向目标设备中写入字符串的长度,所以也能准确地读回写入字符串。 代码示例: 分别通过DataOutputStream类的writeUTF()、writeChars()和 writeBytes() 方法向指定的磁盘文件中写入数据,并通过DatalnputStream类的 readUTF()方法将写入的数据输出到控制台上。
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class DataInOutStream { public static void main(String[] args) { // TODO Auto-generated method stub try { // 创建FileOutputStream对象 FileOutputStream fileOutputStream = new FileOutputStream("word.txt"); // 创建DataOutputStream对象 DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream); dataOutputStream.writeUTF("使用writeUTF()方法写入数据:"); dataOutputStream.writeChars("使用writeChars()方法写入数据:"); dataOutputStream.writeBytes("使用writeBytes()方法写入数据:"); // 将流关闭 dataOutputStream.close(); // 创建FileInputStream对象 FileInputStream fileInputStream = new FileInputStream("word.txt"); // 创建DataInputstream对象 DataInputStream dataInputStream = new DataInputStream(fileInputStream); // 将文件数据输出 System.out.println(dataInputStream.readUTF()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }ZIP压缩管理文件( ZIP archive)是一种十分典型的文件压缩形式,使用它可以节省存储空间。关于ZIP压缩的IO实现,在Java的内置类中提供了非常好用的相关类,所以其实现方式非常简单。使用java.util.zip包中的 ZipOutputStream与 ZiplnputStream类来实现文件的压缩/解压缩。如要从ZIP压缩管理文件内读取某个文件,要先找到对应该文件的“目录进入点”(从它可知该文件在ZIP文件内的位置),オ能读取这个文件的内容。如果要将文件内容写至ZIP文件内,必须先写入对应于该文件的“目录进入点”,并且把要写入文件内容的位置移到此进入点所指的位置,然后再写入文件内容。 Java实现了I/O数据流与网络数据流的单一接口,因此数据的压缩、网络传输和解压缩的实现比较容易。 ZipEntry类产生的对象,是用来代表一个ZIP压缩文件内的进入点(entr) ZiplnputStream类用来读取ZIP压缩格式的文件,所支持的包括已压缩及未压缩的进入点( entry)。 ZipoutputStream类 用来写出ZIP压缩格式的文件,而且所支持的包括已压缩及未压缩的进入点(entry)。利用ZipEntry、ZipInputStream和ZipOutputStream3个Java类实现ZIP数据压缩方式的编程方法。
利用ZipOutputStream类文件,可将文件压缩为.zip文件。ZipOutputStream类的构造方法如下:
方法说明putNextEntry(ZipEntry e)开始写一个新的ZipEntry,并将流内的位置移至此entry所指数据的开头write(bytr[] b,int offset,int len)将字节数组写入当前ZIP条数据finish()完成写入ZIP输出流的内容,无须关闭它所配合的OutputStreamsetComment(String comment)可设置此ZIP文件的注释文字代码示例: 本实例创建类MyZIP,在zip()的方法中实现使用ZipOutputStream类对文件进行压缩,在主方法中调用该方法。
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class MyZIP { private void zip(String zipFileName, File inputFile) { try { // 创建ZipOutputStream类对象 ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName)); // 调用方法 zip(zipOutputStream, inputFile, ""); // 输出信息 System.out.println("压缩中……"); // 将流关闭 zipOutputStream.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 方法重载 private void zip(ZipOutputStream zipOutputStream, File inputFile, String string) { // TODO Auto-generated method stub // 测试此抽象路径名表示的文件是否是一个目录 if (inputFile.isDirectory()) { // 获取路径数组 File[] files = inputFile.listFiles(); try { // 写入此目录的entry ZipEntry zipEntry = new ZipEntry(string + "/"); zipOutputStream.putNextEntry(zipEntry); // 判断参数是否为空 string = string.length() == 0 ? "" : string + "/"; // 循环遍历数组中的文件 for (int i = 0; i < files.length; i++) { zip(zipOutputStream, files[i], string + files[i]); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { // 创建新的进入点 zipOutputStream.putNextEntry(new ZipEntry(string)); // 创建FileInputStream对象 FileInputStream fileInputStream = new FileInputStream(inputFile); // 定义int型变量 int b; System.out.println(string); // 如果没有到达流的尾部 while ((b = fileInputStream.read()) != -1) { // 将字节写入当前ZIP条目 zipOutputStream.write(b); } // 关闭流 fileInputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { // TODO Auto-generated method stub MyZIP myZIP = new MyZIP(); try { // 调用方法,参数名压缩后的文件与要压缩的文件 myZIP.zip("E:\\Projects\\Back-end\\Java\\JavaPractice\\src\\Chapter14\\InOutput\\hello\\hello.zip", new File("E:\\Projects\\Back-end\\Java\\JavaPractice\\src\\Chapter14\\InOutput\\hello")); System.out.println("压缩完成!"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }分析: 从这个实例可以看出,每一个ZIP文件中可能包含多个文件。使用ZipOutputStream类将文件写入目标ZIP文件时,必须先使用ZipOutputStream对象的putNextEntry()方法,写入个别文件的entry,将流内目标指到的位置移到该entry所指的开头位置。执行完之后,在当前目录下会生成一个hello.zip压缩文件。
ZipInputStream类中可读取ZIP压缩格式的文件,包括已压缩和未压缩的条目(entry)。ZipInputStream类的构造方法如下:
ZipInputStream(InputStream in)ZipInputStream类的常用方法:
方法说明read(byte[] b,int offset,int len)读取目标b数组内offset偏移量的位置,长度是len字节available()判断是否已读完目前entry所指定的数据。已读完返回0,否则返回1closeEntry()关闭当前zip条目并定位流以读取下一个条目skip(long n)跳过当前zip条目中指定的字节数getNextEntry()读取下一个ZipEntry,并将流内的位置移至该entry所指数据的开头createZipEntry(String name)以指定的name参数新建一个ZipEntry对象代码示例: 创建类Decompressing,将压缩文件解压到指定文件夹中。
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class Decompressing { public static void main(String[] args) { // TODO Auto-generated method stub try { // 创建ZipInputStream类对象 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("hello.zip")); // 实例化对象,指明要进行解压的文件 ZipEntry entry = zipInputStream.getNextEntry(); // 获取下一个ZipEntry while (((entry = zipInputStream.getNextEntry()) != null) && !entry.isDirectory()) { // 如果entry不为空,并不在同一目录下 获取文件目录 File file = new File("D:\\"+entry.getName()); System.out.println(file); if (!file.exists()) { file.mkdirs(); file.createNewFile(); } zipInputStream.closeEntry(); System.out.println(entry.getName() + "解压成功!"); } zipInputStream.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }