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类库包。
类及方法
1.File常用方法
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() 设置文件为只读 |
2.RamdomAccessFile常用方法
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数值 |
3.FileInputStream常用方法
int | available() 判断该文件是否可读取, |
void | close() 关闭输入流 |
FileDescriptor | getFD() 获得输入流的文件描述对象 |
int | read() 读取一个字节 |
int | read(byte[] b)读取一个字节数组 |
int | read(byte[] b, int off, int len) 读取指定长度的数据到指定数据的位置 |
long | skip(long n) 跳过一定数量的字节 |
4.FileOutputStream常用方法
void | close() 关闭输出流 |
FileDescriptor | getFD() 获得该流的文件描述对象 |
void | write(byte[] b) 输出字节数组 |
void | write(byte[] b, int off, int len) 输出字节数组中指定数据 |
void | write(int b) 输出一个整数(字符) |
5.DataInputStream常用方法
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) 在输入流跳过指定长度字节数。 |
6.DataOutputStream常用方法
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字符串类型数据 |
7.ZipFile常用方法
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("\t" + 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("\t" +" \t" + 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
作者:小a玖拾柒
-------------------------------------------
个性签名: 所有的事情到最後都是好的,如果不好,那說明事情還沒有到最後~
本文版权归作者【小a玖拾柒】,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利!