Welcome
admin
admin

2025-07-18 01:02:57

葡萄牙世界杯球员
9051 160

文件IO流

文件流框架:

9.0 File类

File类,即文件类。

我们如果需要获取文件的信息,或者在磁盘上创建新的文件,就需要用到File类。

File类的对象可以获取文件信息,不涉及文件的读写。文件读写需要用到下面的各种输入输出流。

File类3个构造方法:

File (String filename) (以此创建文件,文件与当前应用程序在同一目录)File(String directoryPath,String filename)File(File dir,String filename)

注:filename是文件名字,directoryPath是文件的路径,dir是目录。

File类常用方法:

public String getName()

调用getName(),获取文件名字

例子:

File f = new File("test.txt");

System.out.println(f.getName()); //=>test.txt

public boolean canRead()

调用canRead(),判断文件是否可读,可读返回true,否则false

例子:

File f = new File("test.txt");

System.out.println(f.canRead()); //=>true

public boolean canWrite()

调用canWrite(),判断文件是否可写,可写返回true,否则false

例子:

File f = new File("test.txt");

System.out.println(f.canWrite()); //=>true

public boolean exists()

调用exists(),判断文件是否存在,存在返回true,否则false

例子:

File f = new File("test.txt");

System.out.println(f.exists()); //=>true

public long length()

调用length(),获取文件长度(单位是字节)

例子:

File f = new File("test.txt");

System.out.println(f.length()); //=>0

public String getAbsolutePath()

调用getAbsolutePath(),获取文件的绝对路径

例子:

File f = new File("test.txt");

System.out.println(f.length()); //=>/Users/console/IdeaProjects/firstTime/test.txt

public String getParent()

调用getParent(),获取文件的父目录

例子:

File f = new File("test.txt");

System.out.println(f.getParent()); //=>null

public boolean isFile()

调用isFile(),判断文件是否是一个普通文件,而不是目录

例子:

File f = new File("test.txt");

System.out.println(f.isFile());//=>true

public boolean isDirectory()

调用isDirectory(),判断文件是否是一个目录。

例子:

File f = new File("test.txt");

System.out.println(f.isDirectory());//=>false

public boolean isHidden()

调用isHidden(),判断文件是否隐藏

例子:

File f = new File("test.txt");

System.out.println(f.isHidden());//=>false

public long lastModified()

调用lastModified(),获取文件最后修改时间(时间戳)

例子:

File f = new File("test.txt");

System.out.println(f.lastModified());//=>1666171192322

public boolean createNewFile()

调用createNewFile(),创建一个新文件,成功返回true,否则false

例子:

File f = new File("test.txt");

f.createNewFile();//创建一个新文件test.txt

public boolean delete()

调用delete(),删除文件,成功返回true,否则false

例子:

File f = new File("test.txt");

f.delete();//删除文件test.txt

*tips:*以上是File类的常用方法,没有囊括全部方法。其他方法需要可自行查询。

9.1 字节流

java以字节为单位去操作文件,可以使用字节流。

java提供了字节输入流:FileInputStream(InputStream子类),字节输出流:FileOutputStream(OutputStream子类)。

字节输入流(FileInputStream)

字节输入流作用:读取文件内容。

读取文件步骤:

打开文件读取文件内容关闭文件

​ 1. 打开文件:

​ 使用2个构造方法打开文件:

FileInputStream(String name);

name是文件名

例子:

// 打开文件时可能出现异常,如文件不存在等,所以都需要用try-catch检测异常。

try{

InputStream fis = new FileInputStream("file.csv");

}

catch (IOException e){

System.out.println(e);

}

FileInputStream(File file);

file是File类对象

例子:

File f = new File("file.csv");

try{

InputStream fis = new FileInputStream(f);

}

catch (IOException e){

System.out.println(e);

}

2.读取文件内容

当打开文件获得FileInputStream对象之后,我们就可以使用对象里的read方法读取文件内容

常用方法:

int read():

调用read(),读取单字节的数据,返回字节值(0-255),未读出字节返回-1

int read(byte b[])

调用read(byte b[]),读取b.length个字节到字节数组b中,返回实际读取的数目。如果达到文件末尾,返回-1

int read(byte b[],int off,int len)

调用read(byte b[],int off,int len),读取len个字节到字节数组b中,返回实际读取的数目。如果达到文件末尾,返回-1,参数off指定从字节数组中的某个位置开始存放读取的数据。

tips: FileInputStream顺序读取文件内容,只要不关闭文件,每次调用read方法就顺序读取文件内容直到末尾

3.关闭文件

虽然程序在结束时自动关闭所有文件,但是显式关闭文件是良好的习惯。

调用close()方法关闭文件。

案例:

File.csv文件内容:123

try{

// 1. 打开文件

InputStream fis = new FileInputStream("file.csv");

// 2. 调用read方法读取内容

int n;

byte[] a = new byte[100];

while((n = fis.read(a,0,100))!=-1){

String s = new String(a,0,n);

System.out.println(s);

}

// 3. 关闭文件

fis.close();

}

catch (IOException e){

System.out.println(e);

}

字节输出流(FileOutputStream)

字节输出流作用:写入文件内容。

写入文件内容步骤:

打开文件写入文件内容关闭文件

​ 1. 打开文件:

​ 使用2个构造方法打开文件:

FileOutputStream(String name,boolean append);

name是文件名,append参数指定是否添加内容到文件末尾,取值true表示从文件末尾开始追加写入的内容,不指定append参数默认取值false表示清除文件内容再写入数据

文件不存在,就会创建文件。

例子:

// 打开文件时可能出现异常,如文件不存在等,所以都需要用try-catch检测异常。

try{

FileOutputStream out = new FileOutputStream("file.csv");

}

catch (IOException e){

System.out.println(e);

}

FileOutputStream(File file,boolean append);

file是File类对象,append参数指定是否添加内容到文件末尾,取值true表示从文件末尾开始追加写入的内容,不指定append参数默认取值false表示清除文件内容再写入数据

文件不存在,就会创建文件。

例子:

File f = new File("file.csv");

try{

FileOutputStream out = new FileOutputStream(f,false);

}

catch (IOException e){

System.out.println(e);

}

写入文件内容

当打开文件获得FileOutputStream对象之后,我们就可以使用对象里的write方法写入文件内容

常用方法:

void write(int a):

调用write(int a),写入单字节的数据a

void write(byte b[])

调用write(byte b[]),写入字节数组的数据

void write(byte b[],int off,ing len)

调用write(byte b[],int off,int len),写入从字节数组b的第off位置处往后的len个字节

tips: FileOutputStream顺序写入文件内容,只要不关闭文件,每次调用write方法就顺序写入文件内容直到文件关闭

关闭文件

在操作系统把所有写入的字节保存到磁盘上之前,有时被保存在内存缓冲区中,通过调用close方法关闭文件可以保证缓冲区

内容写入磁盘。

案例:

File.csv文件内容:123

try{

// 1. 打开文件,如果文件存在,会清除文件内容,文件不存在,就会创建文件

OutputStream fos = new FileOutputStream("file.csv",true);

// 2. 使用wirte方法写入内容,字符串调用getBytes()方法可以得到字符串对应的字节数组

fos.write("happy".getBytes());

// 3. 关闭文件

fos.close();

}

catch(IOException e){

System.out.println(e);

}

运行结束,发现file.csv文件内容变成:123happy

9.2 字符流

上面的字节流是以字节为单位读写文件数据,但是对unicode字符来说,中文字符占了两个字节,处理不当会出现“乱码”现象。

这时候,我们如果要以字符为单位读写文件数据,就得使用到字符流了

java提供:字符输入流:FileReader(Reader子类),字符输出流:FileWriter(Writer子类)

字符输入流(FileReader)

字符输入流作用:读取文件内容。

读取文件步骤:

打开文件读取文件内容关闭文件

打开文件

用构造方法打开文件:

FileReader(String filename)

filename参数是文件名

FileReader(File file)

file参数是File类的对象,也就是先用File类确定文件,在把文件传给FileReader类来构造对象。

读取文件内容

int read():

调用read(),读取单个字符的数据,返回字符的unicode值,未读出字节返回-1

int read(char b[])

调用read(char b[]),读取b.length个字符到字符数组b中,返回实际读取的数目。如果达到文件末尾,返回-1

int read(char b[],int off,int len)

调用read(char b[],int off,int len),读取len个字节到字符数组b中,返回实际读取的数目。如果达到文件末尾,返回-1,参数off指定从字节数组b中的某个位置开始存放读取的数据。

关闭文件

close()

调用close(),关闭文件

案例:

File.txt内容:哈123乐乐happyhappy

try{

// 1.打开文件

FileReader reader = new FileReader("file/file.csv");

char[] a=new char[100];

int n;

// 2.读取文件内容

while((n=reader.read(a,0,100))!=-1){

System.out.println(a);

}

// 3.关闭文件

reader.close();

}

catch (IOException e){

System.out.println(e);

}

输出:哈123乐乐happyhappy

字符输出流(FileWriter)

字符输出流作用:写入文件内容。

写入文件内容步骤:

打开文件写入文件内容关闭文件

打开文件

用构造方法打开文件:

FileWriter(String filename)

filename参数是文件名

FileWriter(String filename, boolean append)

filename参数是文件名

append参数指定是否以从文件末尾追加内容的方式写入

FileWriter(File file)

file参数是File类的对象,也就是先用File类确定文件,在把文件传给FileReader类来构造对象

FileWriter(File file,boolean append)

file参数是File类的对象,也就是先用File类确定文件,在把文件传给FileReader类来构造对象

append参数指定是否以从文件末尾追加内容的方式写入

写入文件内容

void write(char c)

调用write(char c),写入单个字符c

void write(char b[])

调用write(char b[]),把字符数组b数据写入

void write(char b[],int off,int len)

调用write(char b[],int off,int len),写入字符数组的len个字节到文件中,参数off指定从字符数组b中的某个位置开始写入读取的数据

void write(String s)

调用write(String s),把字符串s写入

关闭文件

close()

调用close(),关闭文件

​ 案例:

​ test.txt无内容

try{

// 1.打开文件

FileWriter writer = new FileWriter("file/test.txt");

// 2.写入字符串

writer.write("今天天气真good!\n");

// 3.关闭文件

writer.close();

}

catch (IOException e){

System.out.println("file error:"+e);

}

输出:test.txt文件多了字符串“今天天气真good!”。

9.3 随机流

上面学习了字节流和字符流,我们发现读和写文件是分开的,这时候,我们想,能不能像python那样,读写是可以一起的呢?

当然是可以的啦

java提供了随机流类(RandomAccessFile),使得我们可以既能读也能写~

RandomAccessFile

操作文件过程:

指定模式打开文件读写文件关闭文件

指定模式打开文件

两个构造方法:

RandomAccessFile(String name,String mode)

name 打开文件名

mode 指定以r(只读)或rw(可读写)模式打开

RandomAccessFile(File file,String mode)

file 打开的文件

mode 指定以r(只读)或rw(可读写)模式打开

读写文件

常用方法:

方法功能close()关闭文件getFilePoint()获取当前读写的位置length()获取文件的长度read()从文件中读取一个字节的数据readBoolean()从文件中读取一个布尔值,0代表false,其他代表truereadByte()从文件中读取一个字节readChar()从文件中读取一个字符(2个字节)readDouble()从文件中读取一个双精度浮点值(8个字节)readFloat()从文件中读取一个单精度浮点值(4个字节)readFully(byte b[])读b.length字节放入数组b,完全填满该数组readInt()从文件中读取一个int值(4个字节)readLine()从文件中读取一个文本行readLong()从文件中读取一个长整形(8个字节)readShort()从文件中读取一个短整形(2个字节)readUnsignedByte()从文件中读取一个无符号字节(1个字节)readUnsignedShort()从文件中读取一个无符号短整形(2个字节)readUTF()从文件中读取一个UTF字符串seek(long position)定位读写位置setLength(long newlength)设置文件的长度skipBytes(int n)在文件中跳过给定数量的字节write(byte b[])写入b.length个字节到文件writeBoolean(boolean v)把一个布尔值作为单字节值写入文件writeByte(int v)向文件写入一个字节writeBytes(String s)向文件写入一个字符串writeDouble(double v)向文件写入一个双精度浮点值writeFloat(float v)向文件写入一个单精度浮点值writeInt(int v)向文件写入一个int值writeLong(long v)向文件写入一个long值writeShort(int v)向文件写入一个short值writeUTF(String s)向文件写入一个UTF字符串writeChar(char c)向文件写入一个字符writeChars(String s)向文件写入一个作为字符数据的字符串注意:调用readLine()方法在读取非ASCII字符的文件(比如含有中文字符的文件)会出现“乱码”,因此需要把readLine()读取的字符串用“iso-8859-1”编码重新编码存入byte数组中,然后用当前机器的默认编码将该数组转为字符串。操作如下:

1.读取

String str = in.readLine();

2.“iso-8859-1”重新编码

byte b[] = str.getBytes("iso-8859-1");

3.使用当前机器的默认编码将字节数组转为字符串

String content = new String(b)

案例:

try{

RandomAccessFile inAndOut = new RandomAccessFile("english.txt","rw");

long length = inAndOut.length(); // 获取文件长度

long position = 0;

inAndOut.seek(position); // 设置文件起始位置

while(position

String str = inAndOut.readLine();

byte[] b = str.getBytes("iso-8859-1");

String content = new String(b);

position = inAndOut.getFilePointer();

System.out.println(content);

}

inAndOut.close();

}

catch (IOException e){

System.out.println(e);

}

9.4 数组流

上面学的是从文件中读写数据,java还可以从计算机内存中读写数据。

字节数组流:字节数组输入流(ByteArrayInputStream), 字节数组输出流(ByteArrayOutputStream)

字符数组流:

字节数组输入流(ByteArrayInputStream):

指定读取源:

使用构造方法指定读取源:

ByteArrayInputStream(byte[] buf);

@param buf 要从内存中读取的字节数组的全部字节单元

ByteArrayInputStream(byte[] buf,int offset,int length);

@param buf 要从内存中读取的字节数组

@param offset 指定从offset处开始读取

@param length 指定读取几个字节单元

读取数据

public int read()

调用read()方法,顺序读出一个字节,返回读取的字节值

public int read(byte[] b, int off,int len)

@param b 指定读取的内容存入的数组

@param off 指定读取起始位置

@param len 指定读取的字节数

调用 read(byte[] b, int offing len)方法,从读取源汇中第 off 个字节开始顺序读取 len 个字节的数据,存入b数组中,返回实际读取的字节个数,如果没有读取字节返回-1.

关闭读取源

close()

字节数组输出流(ByteArrayOutputStream)

指定输出源:

使用构造方法指定输出源:

ByteArrayOutputStream();

向一个默认大小而32字节的缓冲区写入内容,如果输出内容字节个数大于缓冲区,缓冲区容量自动增加

ByteArrayOutputStream(int size);

@param size 指定写入到的缓冲区初始大小

向初始大小为size的缓冲区写入内容,如果输出内容字节个数大于缓冲区,缓冲区容量自动增加

输出数据

public void write(int b)

调用write(int b)方法,顺序地向缓冲区写入一个字节

public void write(byte[] b, int off,int len)

@param b 指定把数组b内容写入缓冲区

@param off 指定写入起始位置

@param len 指定写入的字节数

调用 write(byte[] b, int off,int len)方法,

public byte[] to ByteArray()

调用byteArray(),可以返回输出流写入到缓冲区的全部字节

关闭读取源

close()

​ 案例:

try{

//指定写入源:

ByteArrayOutputStream outByte = new ByteArrayOutputStream();

//生成输入内容

byte [] byteContent = "mid-autumn festival ".getBytes();

//把byteContent写入缓冲区

outByte.write(byteContent);

//指定读取源

ByteArrayInputStream inByte = new ByteArrayInputStream(outByte.toByteArray());

byte backByte[] = new byte[outByte.toByteArray().length];

//读取缓冲区内容存入backByte

inByte.read(backByte);

//打印读取的内容

System.out.println(new String(backByte));

//关闭

inByte.close();

outByte.close();

}

catch (IOException e){

System.out.println(e);

}

字符数组流CharArrayReader和CharArrayWriterlei ,与字节数组流对应,字节数组流是把字节数组作为流的源和目标,字符数组流是把字符数组作为流的源和目标。

案例:

try{

// 字符数组流

CharArrayWriter outChar = new CharArrayWriter();

char[] charContent = "中秋快乐".toCharArray();

outChar.write(charContent);

CharArrayReader inChar = new CharArrayReader(outChar.toCharArray());

char backChar[] = new char[outChar.toCharArray().length];

inChar.read(backChar);

System.out.println(new String(backChar));

}

catch (IOException e){

System.out.println(e);

}

9.5 数据流

数据输入流(DataInputStream)

数据输出流(DataOutputStream)

使用数据流,允许按着机器无关的风格读取Java原始数据,也就是说,当读取一个数值时,不必再关心这个数值应当是多少个字节。

DataInputStream构造方法:DataInputStream(InputStream in)

DataOutputStream构造方法:DataOutputStream(OutputStream in)

数据流常用方法:

方法描述close()关闭流readBoolean()读取一个布尔值readByte()读取一个字节readChar()读取一个字符readDouble()读取一个double型数据readFloat()读取一个float型数据readInt()读取一个int型数据readLong()读取一个long型数据readShort()读取一个short型数据readUnsignedByte()读取一个无符号字节readUnsignedShort()读取一个无符号短型readUTF()读取一个UTF字符串skipBytes(int n)跳过给定的字节数writeBoolean(boolean v)写入一个布尔值writeBytes(String s)写入一个字符串writeChars(String s)写入字符串writeDouble(double v)写入一个double型数据writeFloat(float v)写入一个float型数据writeInt(int v)写入一个int型数据writeLong(long v)写入一个long型数据writeShort(int v)写入一个short型数据writeUTF(String s)写入一个UTF字符串

案例:

File file = new File("appl.txt");

// 数据输出流

try{

FileOutputStream fos = new FileOutputStream(file);

DataOutputStream outData = new DataOutputStream(fos);

outData.writeBytes("hehlo");

}

catch(IOException e){

System.out.println(e);

}

// 数据输入流

try{

FileInputStream in = new FileInputStream(file);

DataInputStream inData = new DataInputStream(in);

byte c;

while((c=inData.readByte())!='\0'){

System.out.print((char)c);

}

}

catch (IOException e){

}

9.6 对象流

对象输出流(ObjectOutputStream)

对象输入流(ObjectInputStream)

使用对象流,可以把对象读写到文件。

读写对象时,必须保证对象是序列化的,什么是序列化呢,一个类如果实现了Serializable接口,这个类创建的对象就是序列化对象,java类库提供的绝大多数对象都是序列化的。但是Serializable接口中没有方法,因此实现该接口的类不需要实现额外的方法,用implements Serializable表明这个类实现Serializable接口即可。

ObjectOutputStream构造方法:ObjectOutputStream(OutputStream out)

ObjectInputStream构造方法:ObjectInputStream(InputStream in)

写入方法:writeObject(object)

读入方法: readObject(object)

案例:

TV.java:

import java.io.*;

public class TV implements Serializable{

String name;

int price;

public void setName(String s){

name =s;

}

public void setPrice(int n){

price=n;

}

public String getName(){

return name;

}

public int getPrice(){

return price;

}

}

Example.java:

import java.io.*;

public class Example {

public static void main(String[] args) {

TV changhong = new TV();

changhong.setName("长虹电视");

changhong.setPrice(5678);

File file = new File("telecision.txt");

try {

FileOutputStream fileout = new FileOutputStream(file);

ObjectOutputStream objectOut = new ObjectOutputStream(fileout);

objectOut.writeObject(changhong);

objectOut.close();

FileInputStream fileIn = new FileInputStream(file);

ObjectInputStream objectIn = new ObjectInputStream(fileIn);

TV xinfei = (TV) objectIn.readObject();

objectIn.close();

System.out.println("xinfei name "+xinfei.getName());

System.out.println("xinfei price "+xinfei.getPrice());

xinfei.setName("新飞电视");

xinfei.setPrice(10);

System.out.println("xinfei name "+xinfei.getName());

System.out.println("xinfei price "+xinfei.getPrice());

}

catch (ClassNotFoundException event){

System.out.println("不能读出对象");

}

catch (IOException event){

System.out.println(event);

}

}

}

9.7 序列化与对象克隆

一个类的两个对象如果具有相同的引用,那么他们就拥有相同的实体和功能,即他们指向的内存空间一样,修改其中一个,另一个也随之改变。

如:

A one = new A()

A two = one;

假设A类中有int型成员变量x,当进行下面操作:

one.x = 200;

那么two.x也是200。

那么问题来了,有时候,我们想得到的是一个“复制品”,修改其中一个,另一个不改变,这样的对象就称为原对象的一个克隆对象。

使用对象流很容易获得一个对象的克隆,比如上一小节的案例中,xinfei就是changhong的一个克隆。

那么如何快速获得一个对象的克隆呢?之前是通过对象流读写文件获取,我们还可以通过数组流读写入内存快速获得一个对象的克隆。

案例:单击“写出对象”按钮将标签写入内存,单击“读入对象”按钮读入标签的克隆对象,并改变该克隆对象的文字。

import javax.swing.*;

import java.io.*;

import java.awt.*;

import java.awt.event.*;

public class demo {

public static void main(String[] args) {

MyWin win = new MyWin();

}

}

class MyWin extends JFrame implements ActionListener{

JLabel label = null;

int i=0;

JButton 读入 = null,写出= null;

ByteArrayOutputStream out = null;

MyWin(){

setLayout(new FlowLayout());

label = new JLabel("How are you");

读入=new JButton("读入对象");

写出=new JButton("写出对象");

读入.addActionListener(this);

写出.addActionListener(this);

setVisible(true);

add(label);

add(写出);

add(读入);

setSize(500,400);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

validate();

}

public void actionPerformed(ActionEvent e){

if(e.getSource()==写出){

try{

out = new ByteArrayOutputStream();

ObjectOutputStream objectOut = new ObjectOutputStream(out);

objectOut.writeObject(label);

objectOut.close();

}

catch (IOException ev){

System.out.println(ev);

}

}

else if(e.getSource()==读入){

try{

ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

ObjectInputStream objectIn = new ObjectInputStream(in);

JLabel temp = (JLabel) objectIn.readObject();

temp.setText("第"+i+"次读入");

this.add(temp);

this.validate();

objectIn.close();

i++;

}

catch (Exception event){

System.out.println(event);

}

}

}

}

9.8 使用Scanner解析文件

对于Scanner类,我们可以用来获取键盘的输入,可以解析字符串,也可以解析文件。

使用默认分割标记空格解析文件

File file = new File("student.txt");

Scanner sc = new Scanner(file);

sc就会把空格作为分割标记,调用next()方法依次返回file中的单词,如果file中最后一个单词已被next()返回,sc调用hasNext()就返回false,否则返回true;对于数字型单词,还可以调用nextInt()、nextDoule()等返回数字。

使用正则表达式作为分割标记解析文件

File file = new File("student.txt");

Scanner sc = new Scanner(file);

//设置匹配的正则表达式

sc.useDelimiter("[^0-9.]+");

设置正则表达式后,就以此来分割文件内容,调用next()依次返回分割的单词。

案例:提取文件student.txt中的分数数字

student.txt 内容:小明的成绩是72分,张三的成绩是90分,赵四的成绩是100分。

import java.io.File;

import java.io.IOException;

import java.util.Scanner;

public class Example {

public static void main(String[] args) {

try{

File file = new File("student.txt");

Scanner sc = new Scanner(file);

// 设置匹配的正则表达式

sc.useDelimiter("[^0-9.]+");

while(sc.hasNext()){

System.out.print(sc.next()+" ");

}

}

catch (IOException e){

System.out.println(e);

}

}

}

输出:72 90 100

9.9 文件锁

有时候,遇到好几个程序处理同一个文件的情况,处理不当就可能发生混乱。这时候,保险起见,一个文件在某个时间段内应该只能被一个程序操作,把文件锁住,等处理完了,解锁文件,文件就可以被其他程序操作了。

如何实现呢?java提供了FileLock和FileChannel类来实现文件锁功能。

步骤:

使用RandomAccessFile流以“rw”模式打开文件:

RandomAccessFile input = new RandomAccessFile("Example.java","rw");

input调用方法getChannel()获得一个连接到底层文件的FileChannel对象(信道):

FileChannel channel = input.getChannel();

信道调用tryLock()或lock()方法获得一个FileLock(文件锁)对象,给文件加锁:

FileLock = channel.tryLock();

文件加锁后,禁止任何程序对文件操作或再加锁。对于加锁后的文件,如果想读写文件,就必须让FileLock对象调用release()方法释放文件锁:

lock.release();

案例:java程序通过单击按钮释放文件锁,并读取文件中的一行并马上加锁。其他因此程序无法操作文件,比如用windows记事本程序去改当前文件,但是无法保存。

example.txt 内容:

123

hello

test

WindowFileLock.java:

import java.io.*;

import java.nio.*;

import java.nio.channels.*;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class WindowFileLock extends JFrame implements ActionListener{

JTextArea text;

JButton button;

File file;

RandomAccessFile input;

FileChannel channel;

FileLock lock;

WindowFileLock(File f){

file =f;

try{

input = new RandomAccessFile(file,"rw");

channel = input.getChannel();

lock = channel.tryLock();

}

catch (Exception exp){}

text = new JTextArea();

button = new JButton("读取一行");

button.addActionListener(this);

add(new JScrollPane(text),BorderLayout.CENTER);

add(button,BorderLayout.SOUTH);

setSize(300,400);

setVisible(true);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public void actionPerformed(ActionEvent e){

try{

lock.release();

String lineString = input.readLine();

text.append("\n"+lineString);

lock = channel.tryLock();

if(lineString==null){

input.close();

}

}

catch (Exception ee){}

}

}

MainClass.java:

import java.io.*;

public class MainClass {

public static void main(String[] args) {

File file = new File("example.txt");

WindowFileLock win = new WindowFileLock(file);

win.setTitle("使用文件锁");

}

}

公粽号:为你作画