Java学习---IO操作

基础知识

1.文件操作

     Java语言统一将每个文件都视为一个顺序字节流。每个文件或者结束于一个文件结束标志,或者根据系统维护管理数据中所纪录的具体字节数来终止。当一个文件打开时,一个对象就被创建,同时创建一个流和该对象关联。

   基于Java的平台无关性特点,Java的文件访问机制也是独立于文件系统。为了克服在Windows 和 UNIX系统下,不同的路径分隔符. Windows使用”\”, Unix使用”/”, File类提供了 file.separator静态值来解决分隔符的问题。而绝对路径的约定,在UNIX平台”/”为绝对路径,在Windows平台”E:\”为绝对路径。

Java对文件的操作可通过File和RandomAccessFile类来实现。在文件操作中,java.io.File类是重要类,它提供创建文件和目录以及访问文件信息的有关描述和操作,使用File类注意:它是通过某个路径创建一个File类,并不需要真正存在这个目录或文件,而是通过这个对象来保存对文件和目录的引用。即利用文件名和路径名来实例化一个文件类。

RandomAccessFile类可以处理任何类型的数据文件。该类可以对多种格式的文件进行访问操作,它支持对文件的随机访问,即可以在文件的任意位置上进行数据存取操作。其特点:实现对文件的非顺序方式随机存取;既是输入流,也是输出流, 通过参数决定流的类型。

文件操作中可能出现的异常包括:

l_ IllegalArgumentException,参数不吻合

l_ IOException,输入/输出错误

l_ SecurityException,读写模式不对

l_FileNotFoundException,文件未找到

2.JAVA流

流指一个数据序列,是一种逻辑上的虚拟结构,一端是数据源端,另一端是数据目的端。流的两端都有一定的数据缓冲区用来暂存数据, 数据到达后先保存在缓冲中, 等需要的时候再读取. 发送端也是等缓冲中一定数量的数据后再发送. 这样的设计可以有效的提高传输效率,如图1-1所示。

  流分为输入流(Input Stream)和输出流(Output Stream),在Java中相应提供了两个抽象(abstract)的流操作类InputStream和OutputStream, 并且以这些类为基础, 派生了许多类用于I/O的具体操作

在Java.io包中提供了60多个流相关类,从功能上分为:输入流和输出流;从流结构上可分为:字节流和字符流。

I/O操作的一般步骤如下:

1) 使用引入语句引入java.io包,import java.io.*;

2) 根据不同的数据源和I/O任务,建立字节或者字符流;

3) 若需要对字节或字符流信息组织加工为数据,在已建字节或字符流对象上构建数据流对象;

4) 用输入输出对象类的成员方法进行读写操作,需要时设置读写位置指针;

5) 关闭流对象。

3.文件压缩

在进行网络传输时,为了得到更快的传输速度,经常将待发送的数据进行压缩。在java.util.zip类库包中提供了标准读写zip和gzip文件方法。

l_ZipFile类用于创建一个压缩文件的描述,类似与File类。

l_ ZipEntry类用于创建一个压缩文件的入口描述

Public InputStream getInputStream(ZipEntry entry) throws IOException

遗憾的是,使用Java自带的类 java.util.zip进行文件/目录的压缩的话,有一点不足,不支持中文的名件/目录命名,当待压缩文件名称中,出现中文或非ASIIC码字符时,就会出错。

目前一般的Ant.jar类库中也有zip类,import org.apache.tools.zip.*,能够解决不支持中文文件目录的问题,同时,Ant的获得途径也比较多,一般的应用服务器中有这个包,可在tomcat5.X中找到ant.jar类库包。

类及方法

1File常用方法

boolean

canRead() 判断文件是否可读

 boolean

canWrite()判断文件是否可写

 boolean

createNewFile() 创建新文件

 boolean

delete() 删除文件

 File

getAbsoluteFile() 获得绝对文件类型

 String

getAbsolutePath() 获得绝对路径名

 File

getCanonicalFile() 获得标准文件类型

 String

getCanonicalPath()获得标准文件路径

 String

getName() 获得文件名

 String

getParent() 获得父路径名

 String

getPath() 获得路径名

 boolean

isDirectory() 判断是否为目录

 boolean

isFile()判断是否为文件

 boolean

isHidden()判断是否为隐藏

 long

lastModified()最后修改时间

 long

length() 获得文件长度

 String[]

list() 获得目录中文件名列表

 String[]

list(FilenameFilter filter) 获得目录中指定字符文件列表

 File[]

listFiles() 列出文件类型列表

 boolean

mkdir() 创建目录

 boolean

renameTo(File dest) 更改文件名

 boolean

setLastModified(long time)更改最后文件修改时间

 boolean

setReadOnly() 设置文件为只读

2RamdomAccessFile常用方法

void

close() 关闭该文件流,释放资源

 long

getFilePointer() 获得文件当前指针

 long

length() 获得文件长度

 int

read() 读取数据

 int

read(byte[] b) 读取数据至数组

 int

read(byte[] b, int off, int len) 读取数据至数组指定位置

 boolean

readBoolean() 读取boolean 数据

 byte

readByte() 读取有符号8bit数据

 char

readChar() 读取Unicod字符

 void

readFully(byte[] b) 读取数据byte数组

 int

readInt()读取有符号32bit integer数值

 String

readLine()按行读取数据

 String

readUTF()读取字符串

 void

seek(long pos) 指针跳过指定字符数

 void

setLength(long newLength)设置文件长度

 int

skipBytes(int n) 跳过指定长度的字节数

 void

write(byte[] b) 保存字节数组至文件

 void

write(byte[] b, int off, int len) 保存字节数组指定长度至文件

 void

write(int b)保存int数值

 void

writeBoolean(boolean v) 保存boolean数值

 void

writeByte(int v) 保存byte数值

 void

writeBytes(String s) 保存字符串数值

 void

writeChar(int v) 保存char数值

 void

writeChars(String s) 保存字符串数值

 void

writeInt(int v) 保存int数值

 void

writeUTF(String str) 保存UTF数值

3FileInputStream常用方法

 int

available() 判断该文件是否可读取,

 void

close() 关闭输入流

 FileDescriptor

getFD() 获得输入流的文件描述对象

 int

read() 读取一个字节

 int

read(byte[] b)读取一个字节数组

 int

read(byte[] b, int off, int len) 读取指定长度的数据到指定数据的位置

 long

skip(long n) 跳过一定数量的字节

4FileOutputStream常用方法

 void

close() 关闭输出流

 FileDescriptor

getFD() 获得该流的文件描述对象

 void

write(byte[] b) 输出字节数组

 void

write(byte[] b, int off, int len) 输出字节数组中指定数据

 void

write(int b) 输出一个整数(字符)

5DataInputStream常用方法

 int

read(byte[] b) 从输入流读取数据至字节数组中。

 int

read(byte[] b, int off, int len) 从输入流读取数据至字节数组中指定位置和长度。

 boolean

readBoolean() 读取boolean类型数据

 byte

readByte() 读取byte类型数据

 char

readChar() 读取char类型数据

 int

readInt()读取int类型数据

 String

readUTF()读取UTF类型数据

 int

skipBytes(int n) 在输入流跳过指定长度字节数。

6DataOutputStream常用方法

void

flush() 立刻输出

 int

size() 返回输出流字节数

 void

write(byte[] b, int off, int len)输出数组中指定位置和长度的byte数

 void

write(int b)输出int类型数据

 void

writeBoolean(boolean v) 输出boolean类型数据

 void

writeByte(int v) 输出byte类型数据

 void

writeBytes(String s) 以字节形式输出String类型数据

 void

writeChar(int v) 输出char类型数据

 void

writeChars(String s) 输出String类型数据

 void

writeInt(int v) 输出int类型数据

 void

writeUTF(String str) 输出UTF字符串类型数据

7ZipFile常用方法

void

close() 关闭

 Enumeration

entries() 返回ZIP文件列表

protected  void

finalize() 保证ZIP操作正确完成

 ZipEntry

getEntry(String name) 获得ZIP入口

 InputStream

getInputStream(ZipEntry entry) 获得ZIP输入流

 String

getName()获得ZIP文件名

 int

size()获得ZIP文件包内被压缩的文件数量

代码示例

File类方法练习 

 1 import java.io.*;
 2 class exp_4_2{
 3     public static void main(String [] args){
 4         try{
 5             File myFile = new File("d:\f-disk\test.xml");
 6             System.out.println(myFile.getName() + "是目录?"+myFile.(               ));
 7             System.out.println("可读/写?" + 
 8                  myFile.canRead() + "/"+myFile.(              ));
 9             System.out.println("文件字节长度"+myFile.length());
10             System.out.println(_________________);
11             System.out.println(myFile.getParent());
12             System.out.println(myFile.getAbsolutePath());
13             File newFile = new File("testNew.java");
14             myFile.renameTo(newFile);     
15             System.out.println("修改该文件名为:testNew.java");
16             System.out.println("目录中有以下文件:");
17             File myDir = new File(myFile.getParent());
18             String [] files = myDir.(            );
19             for(int i=0; i<files.length; i++){
20                 System.out.println(files[i]);
21             }
22         }catch(Exception e){
23             System.err.println(e.toString());
24         }
25     }
26 }
View Code

 输入字符和数据

 1 //注意C3的输出结果,解释为什么会得到该结果
 2 import java.io.*;
 3 class exp_4_1a{
 4     public static void main(String [] args){
 5         try{
 6             int c1 = System.in.read();
 7             System.out.println("c1 = " + c1);
 8             char c2 = (char)c1;
 9             System.out.println("c2 = " + c2);
10             char c3 = (char)System.in.read();
11             System.out.println("c3 = " + c3);
12         }catch(Exception e){
13             System.err.println(e.getMessage());
14         }
15     }
16 }
17 #############################################
18 import java.io.*;
19 class exp_4_1b{
20     public static void main(String args[])throws IOException{
21         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
22         System.out.print("输入一个整数:");
23         String str = br.readLine();
24         int i = Integer.parseInt(str);
25         System.out.print("输入一个实数:");            
26         String str = br.readLine();
27         float f = Float.parseFloat(str);
28         System.out.println("它们的和是" + ( i + f));
29     }
30 }
31 #############################################
32 import java.util.*;
33 public class exp_4_1c{
34     public static void main(String args[]){
35         System.out.println("请输入若干个数,每输入一个数用回车确认");
36         System.out.println("最后输入一个非数字结束输入操作");
37         Scanner reader=new Scanner(System.in);
38         double sum=0;
39         int m=0;
40         while(reader.hasNextDouble()){
41             double x=reader.nextDouble();
42             m=m+1;
43             sum=sum+x;
44         }
45         System.out.println("%d个数的和为%f/n",m,sum);
46         System.out.println("%d个数的平均值是%f/n",m,sum/m);
47 } }
View Code

显示程序文件当前所在的目录树结构

 1 import java.io.*;
 2 
 3 class exp_4_2{
 4     public static void main(String args[]){
 5         File dir = new File(System.getProperty("user.dir"));   //获得程序当前运行路径
 6         File filename = null;
 7         
 8         if(dir.isDirectory()){
 9             System.out.println("Directory of " + dir);
10             String listing[] = dir.list();
11             
12             for(int i=0;i<listing.length;i++){
13                 System.out.println("	" + listing[i]);
14                 
15                 filename = new File(listing[i]);
16                 
17                 if(filename.isDirectory()){
18                     
19                     String listing2[] = filename.list();
20                     for(int j=0;j<listing2.length;j++){
21                         System.out.println("	" +" 	" + listing2[j]);
22                     }
23                 }
24             }
25 } } }
View Code

保存数据,发现并修改其中错误

 1 import java.io.*;
 2 class exp_4_3{
 3     public static void main(String args[]){
 4         try{
 5             OutputStream fos = new FileOutputStream("fib.dat");
 6             DataOutputStream dos = new DataOutputStream(fos);
 7             int i = 1, j = 1;
 8             for(int count =0;count<20;count++){
 9                 dos.writeInt(i);
10                 int k = i + j;
11                 i = j;
12                 j = k;
13              }
14              dos.flush();
15              dos.close();
16              fos.close();
17          }catch(Exception e){
18              System.err.println(e.toString());
19          }
20         try{
21             InputStream fis = new FileInputStream("fib.dat");
22             DataInputStream dis = new DataInputStream(fis);
23             int k = 0;
24             while(k != -1){
25                 k = dis.readInt();
26                 System.out.println(k);
27             }
28             dis.close();
29             fis.close();
30         }catch(Exception e){
31             System.err.println(e.toString());
32 } } }
View Code

合并文件

 1 import java.io.*;
 2 import java.util.*;
 3 //该类提供了对向量的包装,返回根据文件名打开的FileInputStream.
 4 class InputStreamEnumerator implements Enumeration {
 5   PRivate Enumeration files;
 6   public InputStreamEnumerator(Vector files) {
 7     this.files = files.elements();
 8   }
 9   public boolean hasMoreElements() {
10     return files.hasMoreElements();
11   }
12   public FileInputStream nextElement() {
13     try {
14       return new FileInputStream(files.nextElement().toString());
15     } catch (IOException e) {
16       return null;
17     }
18   }
19 }
20 class exp_4_4 {
21   public static void main(String args[])
22     throws IOException {
23     int c;
24     Vector files = new Vector();
25     files.addElement("c:/java/1.txt");
26     files.addElement("c:/java/2.txt");
27     InputStreamEnumerator e = new InputStreamEnumerator(files);
28     InputStream input = new SequenceInputStream(e);
29     while ((c = input.read()) != -1) {
30       System.out.print((char) c);
31     }
32     input.close();
33 } }
View Code

通过网络传输指定文件

服务端:

 1 服务器端实现代码:
 2 import java.io.*;
 3 import java.net.*;
 4 
 5 public class FileServer{
 6 public static void main(String[] args)throws Exception{
 7   //创建文件流用来读取文件中的数据
 8   File file=new File("lishengjie.jpg");
 9   FileInputStream fos=new FileInputStream(file);
10 
11   //创建网络服务器接受客户请求
12   ServerSocket ss=new ServerSocket(3108);
13   Socket client=ss.accept();
14 
15   //创建网络输出流并提供数据包装器
16   OutputStream netOut=client.getOutputStream();
17   OutputStream doc=new DataOutputStream(new
18  BufferedOutputStream(netOut));
19 
20   //创建文件读取缓冲区
21   byte[] buf=new byte[2048];
22   int num=fos.read(buf);
23   while(num!=(-1)){           //是否读完文件
24     doc.write(buf,0,num);      //把文件数据写出网络缓冲区
25     doc.flush();              //刷新缓冲区把数据写往客户端
26     num=fos.read(buf);        //继续从文件中读取数据
27   }
28   fos.close();
29   doc.close();
30   }
31 }
View Code

客户端:

 1 客户方实现代码:
 2 import java.io.*;
 3 import java.net.*;
 4 
 5 public class FileClient{
 6   public static void main(String[] args)throws Exception{
 7     //使用本地文件系统接受网络数据并存为新文件
 8     File file=new File("newFile.jpg");
 9     file.createNewFile();
10     RandomAccessFile raf=new RandomAccessFile(file,"rw");
11 
12     // 通过Socket连接文件服务器
13     Socket server=new Socket(InetAddress.getLocalHost(),3108);
14     //创建网络接受流接受服务器文件数据 
15     InputStream netIn=server.getInputStream();
16     InputStream in=new DataInputStream(new
17  BufferedInputStream(netIn));
18 
19     //创建缓冲区缓冲网络数据
20     byte[] buf=new byte[2048];
21     int num=in.read(buf); 
22     while(num!=(-1)){             //是否读完所有数据
23       raf.write(buf,0,num);         //将数据写往文件
24       raf.skipBytes(num);          //顺序写文件字节
25       num=in.read(buf);           //继续从网络中读取文件
26     }
27     in.close();
28     raf.close();
29   }
30 }
View Code

文件压缩和解压缩,尝试压缩和解压缩带子目录的目录,解决汉字显示问题

压缩:

 1 import java.text.*;
 2 import java.util.zip.*;
 3 import java.io.*;
 4 class Zipper{
 5     String zipTarget;
 6     String zipSource;
 7     Zipper(String fileTarget, String fileSource){
 8         zipTarget = fileTarget;
 9         zipSource = fileSource;
10     }
11     public void compress(){
12         try{
13             FileOutputStream fout = new FileOutputStream(zipTarget);
14             ZipOutputStream zout = new ZipOutputStream(fout);
15             zout.setLevel(9); 
16             File file = new File(zipSource);
17             if(file.isDirectory()){
18                 String [] fileList = file.list();
19                 for(int i=0;i<fileList.length; i++){
20                     ZipEntry ze = new ZipEntry(fileList[i]);
21                     System.out.println("正在压缩文件 " + fileList[i]);
22                     FileInputStream fin = new FileInputStream(file+"\"+fileList[i]);
23                     zout.putNextEntry(ze);
24                     int c = -1;
25                     while((c = fin.read()) != -1){
26                         zout.write(c);
27                     }
28                     fin.close();
29                 }
30             }
31             zout.closeEntry();
32             zout.close();
33         }catch(Exception e){
34             System.err.println(e.toString());
35         }
36     }
37     public static void main(String [] args){
38         Zipper z = new Zipper("history.zip", "zip");
39         z.compress();
40     }
41 }
View Code

解压:

 1 import java.util.*;
 2 import java.text.*;
 3 import java.util.zip.*;
 4 import java.io.*;
 5 
 6 class UnZipper{
 7     String zipSource;
 8     UnZipper(String zipFile){
 9         zipSource = zipFile;
10     }
11     
12     public void unCompress(){
13         try{
14             ZipFile zf = new ZipFile(zipSource);
15             Enumeration es = zf.entries();
16             System.out.println("开始解压缩");
17             while(es.hasMoreElements()){
18                 ZipEntry ze = (ZipEntry)es.nextElement();
19                 System.out.println("当前解压文件为:" + ze.getName());
20                 if(ze.isDirectory()){
21                     File ff = new File("newZip", ze.getName());
22                     ff.mkdirs();
23                 }else{
24                     InputStream in = zf.getInputStream(ze);
25                     File ff = new File("newZip", ze.getName());
26                     File fp = ff.getParentFile();
27                     fp.mkdirs();
28                     FileOutputStream fout = new FileOutputStream(ff);
29                     int c;
30                     while((c = in.read()) != -1)fout.write(c);
31                 }
32              }
33           }catch(Exception e){
34              System.err.println(e.toString());
35           }
36      }
37      
38     public static void main(String [] args){
39         UnZipper uz = new UnZipper("history.zip");
40         uz.unCompress();
41     }
42 }
View Code
原文地址:https://www.cnblogs.com/ftl1012/p/9347582.html