Java文件操作(一)

来源:互联网 发布:厦门雅迅网络很烂吗 编辑:程序博客网 时间:2024/05/15 23:44

java文件操作(转载)

1、课程名称:JAVA文件操作
File、输入、输出流、对象序列化
2、知识点
2.1、上次课程的主要知识点
1、 String与StringBuffer的区别
String一旦声明之后内容不可改变,可以直接赋值,连接可以用+号
StringBuffer的内容可以改变,必须实例化之后赋值
2、 Class类的作用
Class表示反射机制,表示一切类的组成
通过Class.forName()可以找到一个类,之后通过newInstance()实例化,但是要求使用此种方式的时候类中必须存在无参构造方法。
3、 比较器 —— Comparable
用于为一个对象进行排序操作
4、 日期操作类:
SimpleDateFormat ? Date ?日期显示
5、 正则表达式:
验证字符串的组成
拆分、替换
6、 使用正则验证email地址
public class RegDemo{
public static void main(String args[]){
String str = "a@aa.com.cn" ;
// com com.cn cn net net.cn org edu
System.out.println(str.matches("\\w+@\\w+.((com)|(com.cn)|(cn)|(net)|(net.cn)|(org)|(edu))")) ;
}
}
2.2、本次预计讲解的知识点
1、 File类的作用及使用
2、 字节输入流/字节输出流、字符输入流/字符输出流
3、 内存操作流
4、 打印流
5、 对象序列化
3、具体内容
在整个JAVA中所有的文件操作都是使用java.io包完成的,此包中包含了各种操作的类及接口。
IO包中有以下几个主要部分组成:
表示与文件本身的操作:File
IO的输入、输出类
对象序列化
3.1、File类(重点)
在整个IO包中,File类是唯一表示文件本身的,即:文件的创建、删除、存在与否的判断。
File类在使用的时候需要指定操作的文件路径,构造方法:
public File(String pathname)
例如:现在使用File类在硬盘上创建一个新的文件(e:\abc.txt)
创建文件的方法:public boolean createNewFile() throws IOException
import java.io.* ;
public class IODemo01{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\abc.txt") ;
try{
System.out.println(f.createNewFile()) ;
}catch(Exception e){}
}
}
例如:删除在硬盘上建立好的文件
删除文件的方法:public boolean delete()
import java.io.* ;
public class IODemo02{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\abc.txt") ;
// 删除文件
f.delete() ;
}
}
但是以上有一个问题,至少文件存在之后才可以删除。证明,在删除之前需要先判断此文件是否存在,判断语法:public boolean exists();
import java.io.* ;
public class IODemo03{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\abc.txt") ;
if(f.exists()){
// 删除文件
f.delete() ;
}
}
}
例如:要求完成以下的功能
如果文件存在则删除,如果文件不存在则创建
import java.io.* ;
public class IODemo04{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\abc.txt") ;
if(f.exists()){
// 删除文件
f.delete() ;
}else{
try{
f.createNewFile() ;
}catch(Exception e){}
}
}
}
发现此种操作并不是立刻生效的,有一定时间的延迟。
注意:
如果在程序中直接输出File类的对象,则会打印路径名称。
import java.io.* ;
public class IODemo05{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\abc.txt") ;
System.out.println(f) ;
}
}
输出结果:
e:\abc.txt
例如:要求列出一个目录下的所有内容
方法名称如下:
public String[] list():只列出了所有的文件夹或文件的名称,不是绝对路径
public File[] listFiles():取得的是绝对路径
A、使用list()方法操作:
import java.io.* ;
public class IODemo06{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\") ;
String s[] = f.list() ;
for(int i=0;i<s.length;i++){
System.out.println(s[i]) ;
}
}
}
B、使用listFiles()方法操作
import java.io.* ;
public class IODemo07{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\") ;
File fs[] = f.listFiles() ;
for(int i=0;i<fs.length;i++){
System.out.println(fs[i]) ;
}
}
}
例如:区分一个给定的路径是文件还是文件夹
方法名称:public boolean isDirectory()
import java.io.* ;
public class IODemo08{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\") ;
System.out.println(f.isDirectory()) ;
}
}
思考:
任意给定一个路径,要求把此路径下的所有文件包括各个子文件夹的文件全部列出。
思路:
|- 通过给定的路径判断是否是一个文件夹
|- 如果是一个文件夹,则继续列出里面的内容
|- 之后再将此文件夹里面的内容继续判断,观察是否是目录
import java.io.* ;
public class IODemo09{
public static void main(String args[]){
// 告诉系统准备操作这样的一个文件
File f = new File("e:\\") ;
print(f) ;
}
public static void print(File f){
if(f.isDirectory()){
File files[] = f.listFiles() ;
try{
for(int i=0;i<files.length;i++){
// 如果还有子文件夹,则肯定继续列出
print(files[i]) ;
}
}catch(Exception e){}
}else{
System.out.println(f) ;
}
}
}
3.2、RandomAccessFile类(了解)
RandomAccessFile:实现随机访问,可以在文件之中跳转。
在保存内容的时候,必须指定内容的长度。
现在向文件之中写入如下数据:
zhangsan 30
lisi 31
wangwu 32
例如:通过RandomAccessFile类向文件中保存内容
构造方法:public RandomAccessFile(File file,String mode) throws FileNotFoundException
String mode:表示的是文件的打开模式:
只读:r,但是使用此种方式的时候必须保证文件存在。
读写:rw,使用此种方式的时候,向文件中写入数据,如果文件不存在,则会自动创建一个新的文件出来

向文件中写数据:
向文件中写入字符串:public final void writeBytes(String s) throws IOException
向文件中写入数字:public final void writeInt(int v) throws IOException
文件操作之后必须关闭:
关闭:public void close() throws IOException
利用以上方法完成文件的写入,可是写的时候,必须注意,所有的内容长度必须固定。
import java.io.* ;
public class IODemo10{
public static void main(String args[]) throws Exception{
File f = new File("e:"+File.separator+"hello.txt") ;
RandomAccessFile raf = null ;
// 如果文件不存在,则会自动创建一个
raf = new RandomAccessFile(f,"rw") ;
String name = null ;
int age = 0 ;
name = "zhangsan" ;
age = 30 ;
raf.writeBytes(name) ;
raf.writeInt(age) ;
name = "lisi " ;
age = 31 ;
raf.writeBytes(name) ;
raf.writeInt(age) ;
name = "wangwu " ;
age = 32 ;
raf.writeBytes(name) ;
raf.writeInt(age) ;
raf.close() ;
}
}
例如:通过RandomAccessFile取出里面的内容
因为是读,所以可以使用只读的方式打开文件:r
读字符串:public final byte readByte() throws IOException
使用byte的方式读取进来
读数字:public final int readInt() throws IOException
跳过指定长度的内容:public int skipBytes(int n) throws IOException
跳回位置:public void seek(long pos) throws IOException
import java.io.* ;
public class IODemo11{
public static void main(String args[]) throws Exception{
File f = new File("e:"+File.separator+"hello.txt") ;
RandomAccessFile raf = null ;
// 如果文件不存在,则会自动创建一个
raf = new RandomAccessFile(f,"r") ;
String name = null ;
int age = 0 ;
byte b[] = new byte[8] ;
// 跳过第一个人的信息
raf.skipBytes(12) ;
for(int i=0;i<b.length;i++){
b[i] = raf.readByte() ;
}
age = raf.readInt() ;
name = new String(b) ;
System.out.println("姓名:" + name) ;
System.out.println("年龄:" + age) ;
raf.seek(0) ;
for(int i=0;i<b.length;i++){
b[i] = raf.readByte() ;
}
age = raf.readInt() ;
name = new String(b) ;
System.out.println("姓名:" + name) ;
System.out.println("年龄:" + age) ;
raf.close() ;
}
}
3.3、字节流、字符流操作类(重点)
文件操作的基本流程:
1、 通过File类找到一个文件
2、 通过File类去实例化字节流、字符流操作类
3、 进行读或写的操作,在写的时候如果文件不存在则会自动创建
4、 关闭文件
3.3.1、字节流
在字节流中分为两种:
输出流:OutputStream
输入流:InputStream
例如:向文件之中打印一个“Hello World!!!”。
肯定使用输出流。
定义:public abstract class OutputStream extends Objec timplements Closeable, Flushable
OutputStream子类:FileOutputStream
构造方法:public FileOutputStream(File file) throws FileNotFoundException
输出方法:public void write(byte[] b) throws IOException
可以发现只能写出一个byte数组,那么现在是一个字符串,如果要想使用此种方式,需要将一个字符串变为一个byte数组,String中的方法:public byte[] getBytes() 。
关闭:public void close() throws IOException
import java.io.* ;
public class IODemo12{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
OutputStream out = null ;
try{
// 通过子类实例化
out = new FileOutputStream(f) ;
}catch(Exception e){}
String str = "Hello World!!!" ;
byte b[] = str.getBytes() ;
try{
out.write(b) ;
}catch(Exception e){}
try{
out.close() ;
}catch(Exception e){}
}
}
例如:既然可以通过OutputStream向文件中写入内容,那么就一定可以从文件中读取内容,使用InputStream读取内容。
InputStream也是一个抽象类,所以必须使用其子类:FileInputStream
读的方式:
public int read(byte[] b) throws IOException
传入一个byte数组,将所有的内容保存在byte数组之中。
此方法返回向数组中写入数据的个数
将byte数组变为字符串:public String(byte b[])、public String(byte b[],int be,int len)
import java.io.* ;
public class IODemo13{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
InputStream input = null ;
try{
// 通过子类实例化
input = new FileInputStream(f) ;
}catch(Exception e){}
byte b[] = null ;
int len = 0 ;
try{
b = new byte[1024] ;
// 把所有的内容读到数组b中
// 返回读取的个数
len = input.read(b) ;
}catch(Exception e){}
try{
input.close() ;
}catch(Exception e){}
System.out.println(new String(b,0,len)) ;
}
}
但是读取的时候发现程序中开辟了一个很大的byte数组,不用的空间有些浪费,那能否根据文件的大小开辟呢?
File类中有取得文件长度的方法。
import java.io.* ;
public class IODemo14{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
InputStream input = null ;
try{
// 通过子类实例化
input = new FileInputStream(f) ;
}catch(Exception e){}
byte b[] = null ;
try{
b = new byte[(int)f.length()] ;
// 把所有的内容读到数组b中
// 返回读取的个数
input.read(b) ;
}catch(Exception e){}
try{
input.close() ;
}catch(Exception e){}
System.out.println(new String(b)) ;
}
}
如果现在不知道文件大小,该怎么读呢?
读取方法:
public abstract int read() throws IOException
如果读取的内容不是“-1”,就表示还有文件,可以继续读
import java.io.* ;
public class IODemo15{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
InputStream input = null ;
try{
// 通过子类实例化
input = new FileInputStream(f) ;
}catch(Exception e){}
byte b[] = null ;
try{
b = new byte[(int)f.length()] ;
int x = 0 ;
int foot = 0 ;
while((x=input.read())!=-1){
b[foot] = (byte)x ;
foot++ ;
}
}catch(Exception e){
System.out.println(e) ;
}
try{
input.close() ;
}catch(Exception e){}
System.out.println(new String(b)) ;
}
}
3.3.2、字符流
一个字符 = 两个字节(看计算机系统情况而定)。
在字符流操作中,主要使用以下两个类:
字符输出流:Writer
字符输入流:Reader
例如:向文件中保存一个数据
写内容的方法:public void write(String str) throws IOException
import java.io.* ;
public class IODemo16{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
Writer out = null ;
try{
// 通过子类实例化
out = new FileWriter(f) ;
}catch(Exception e){}
String str = "Hello World!!!" ;
try{
out.write(str) ;
}catch(Exception e){}
try{
out.close() ;
}catch(Exception e){}
}
}
例如:从文件中把内容读取进来
读的方法:
public int read(char[] cbuf) throws IOException
public int read() throws IOException


import java.io.* ;
public class IODemo17{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
Reader input = null ;
try{
// 通过子类实例化
input = new FileReader(f) ;
}catch(Exception e){}
char c[] = null ;
int len = 0 ;
try{
c = new char[(int)f.length()] ;
len = input.read(c) ;
}catch(Exception e){
System.out.println(e) ;
}
try{
input.close() ;
}catch(Exception e){}
System.out.println(new String(c,0,len)) ;
}
}
当然,也可以使用read()方法读取内容,代码如下:
import java.io.* ;
public class IODemo18{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
Reader input = null ;
try{
// 通过子类实例化
input = new FileReader(f) ;
}catch(Exception e){}
char c[] = null ;
try{
c = new char[(int)f.length()] ;
int x = 0 ;
int foot = 0 ;
while((x=input.read())!=-1){
c[foot] = (char)x ;
foot++ ;
}
}catch(Exception e){
System.out.println(e) ;
}
try{
input.close() ;
}catch(Exception e){}
System.out.println(new String(c)) ;
}
}
3.3.3、字节流和字符流的区别
字节与字符的不同在于:
所有的文件不管是使用Output、Writer实际上最终保存在文件上的都是字节。
字符是在内存中形成的。
例如:观察以下代码
使用字节流输出,但是并没有关闭
import java.io.* ;
public class IODemo19{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
OutputStream out = null ;
try{
// 通过子类实例化
out = new FileOutputStream(f) ;
}catch(Exception e){}
String str = "Hello World!!!" ;
byte b[] = str.getBytes() ;
try{
out.write(b) ;
}catch(Exception e){}
}
}
以上代码是使用字节流进行操作,但是文件本身并没有关闭,证明字节流是直接操作文件本身的。
那么,同样,将以上的字节流输出换为字符流输出:
import java.io.* ;
public class IODemo20{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
Writer out = null ;
try{
// 通过子类实例化
out = new FileWriter(f) ;
}catch(Exception e){}
String str = "Hello World!!!" ;
try{
out.write(str) ;
}catch(Exception e){}
}
}
运行之后,发现文件虽然已经创建,但是所有的内容并没有写进去,这是因为对于字符流在关闭操作的时候,会强制性的将缓存清空,那么以上代码并没有关闭,所以现在的内容还在缓存里,并没有直接到文件之中。

那么面对上面的情况,如果不关闭文件该如何解决呢?
在Writer类中提供了一个强制性清空缓存的操作:public abstract void flush() throws IOException
例如:修改之前的操作,清空缓存
import java.io.* ;
public class IODemo21{
public static void main(String[] args){
// 通过File找到一个文件
File f = new File("e:\\hello.txt") ;
// 输出流操作类
Writer out = null ;
try{
// 通过子类实例化
out = new FileWriter(f) ;
}catch(Exception e){}
String str = "Hello World!!!" ;
try{
out.write(str) ;
out.flush() ;
}catch(Exception e){}
}
}
但是:
一般程序对于字节流的使用相对较多,例如:图片、多媒体文件。
3.3.4、COPY功能的实现
命令格式:copy e:\hello.txt e:\abc.ini
此命令中有相关的错误提示。
那么现在要求使用JAVA编写这样的一个命令,例如:Java的类为Copy.class,则可以通过初始化参数的方式输入两个路径,例如:java Copy 路径1 路径2。
数据应该边读边写
要确定源路径是否存在及语法格式是否正确。
import java.io.* ;
public class Copy{
public static void main(String args[]) throws Exception{
// 判断参数
if(args.length!=2){
System.out.println("命令语法不正确。") ;
System.exit(1) ;
}
// 再判断源文件是否存在
File f1 = new File(args[0]) ;
if(!f1.exists()){
System.out.println("系统找不到指定的文件。") ;
System.exit(1) ;
}
File f2 = new File(args[1]) ;

//source ;
InputStream input = new FileInputStream(f1) ;

//dest;
OutputStream out = new FileOutputStream(f2) ;
int x = 0 ;
while((x=input.read())!=-1){
out.write(x) ;
}
System.out.println("拷贝完成。") ;
input.close() ;
out.close() ;
}
}

0 0