java文件操作(超详细!)

article/2025/9/23 3:18:51
  1. 文件IO流

文件流框架

9.0 File类

File类,即文件类。

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

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

  • File类3个构造方法:

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

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

  • File类常用方法:

    1. public String getName()

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

      例子

      File f = new File("test.txt");
      System.out.println(f.getName()); //=>test.txt
      
    2. public boolean canRead()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.canRead()); //=>true
      
    3. public boolean canWrite()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.canWrite()); //=>true
      
    4. public boolean exists()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.exists()); //=>true
      
    5. public long length()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.length()); //=>0
      
    6. public String getAbsolutePath()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.length()); //=>/Users/console/IdeaProjects/firstTime/test.txt
      
    7. public String getParent()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.getParent()); //=>null
      
    8. public boolean isFile()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.isFile());//=>true
      
    9. public boolean isDirectory()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.isDirectory());//=>false
      
    10. public boolean isHidden()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.isHidden());//=>false
      
    11. public long lastModified()

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

      例子:

      File f = new File("test.txt");
      System.out.println(f.lastModified());//=>1666171192322
      
    12. public boolean createNewFile()

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

      例子:

      File f = new File("test.txt");
      f.createNewFile();//创建一个新文件test.txt
      
    13. 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. 读取文件内容
    3. 关闭文件

    ​ 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. 写入文件内容
    3. 关闭文件

​ 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);}
  1. 写入文件内容

    当打开文件获得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方法就顺序写入文件内容直到文件关闭

  2. 关闭文件

    在操作系统把所有写入的字节保存到磁盘上之前,有时被保存在内存缓冲区中,通过调用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)

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

    读取文件步骤:

    1. 打开文件
    2. 读取文件内容
    3. 关闭文件
    1. 打开文件

      用构造方法打开文件:

      • FileReader(String filename)

        filename参数是文件名

      • FileReader(File file)

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

    2. 读取文件内容

      • 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中的某个位置开始存放读取的数据。

    3. 关闭文件

      • 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)

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

    写入文件内容步骤:

    1. 打开文件
    2. 写入文件内容
    3. 关闭文件
    1. 打开文件

      用构造方法打开文件:

      • 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参数指定是否以从文件末尾追加内容的方式写入

    2. 写入文件内容

      • 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写入

    3. 关闭文件

      • 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

    操作文件过程:

    1. 指定模式打开文件
    2. 读写文件
    3. 关闭文件
    1. 指定模式打开文件

      两个构造方法:

      • RandomAccessFile(String name,String mode)

        name 打开文件名

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

      • RandomAccessFile(File file,String mode)

        file 打开的文件

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

    2. 读写文件

      常用方法:

      方法功能
      close()关闭文件
      getFilePoint()获取当前读写的位置
      length()获取文件的长度
      read()从文件中读取一个字节的数据
      readBoolean()从文件中读取一个布尔值,0代表false,其他代表true
      readByte()从文件中读取一个字节
      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<length){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):

    1. 指定读取源:

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

      • ByteArrayInputStream(byte[] buf);

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

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

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

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

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

    2. 读取数据

      • 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.

    3. 关闭读取源

      • close()
  • 字节数组输出流(ByteArrayOutputStream)

    1. 指定输出源:

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

      • ByteArrayOutputStream();

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

      • ByteArrayOutputStream(int size);

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

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

    2. 输出数据

      • 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(),可以返回输出流写入到缓冲区的全部字节

    3. 关闭读取源

      • 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提供了FileLockFileChannel类来实现文件锁功能。

  • 步骤:

    • 使用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("使用文件锁");}
}

公粽号:为你作画


http://chatgpt.dhexx.cn/article/03sx4jld.shtml

相关文章

【Java】File 文件

文件操作 File 类 属性 修饰符及类型属性说明static StringpathSeparator路径分隔符&#xff0c;String 类型表示static charpathSeparator路径分隔符&#xff0c;char 类型表示 构造方法 方法签名说明File(File parent, String child)根据父目录 File 对象 孩子路径&…

java文件如何运行

.java文件先用 javac 进行编译&#xff0c;生成 .class文件&#xff0c;在用 java 生成结果 .java&#xff08;源文件&#xff09;.class&#xff08;字节码文件&#xff09; 1.在Sublime中&#xff1a;新建文件&#xff0c;另存为 D:\javacode\Hello.java //这是java的快速入…

Java指令编译java文件

Java指令编译java文件 1. 进入cmd2. 编译2.1 切换不同JDK编译文件 3. 运行 1. 进入cmd 如何快速进入/打开cmd–快捷键 在源代码目录输入cmd&#xff0c;然后回车 2. 编译 如果出现错误: 编码 GBK 的不可映射字符 (0x8D) 需要在javac 后面加上 -encoding UTF-8 javac -enco…

Java File文件操作

Java提供File类&#xff0c;让我们对文件进行操作&#xff0c;简单整理了一下File类的用法。 1.基本概念 File&#xff1a;文件和目录路径名的抽象表示形式&#xff0c;代表文件或者文件夹。 2.构造方法 // 根据parent抽象路径名和child路径名字符串创建一个新File实例File(F…

Java 文件基本技术 文件概述

这里写目录标题 13.1 文件概述13.1.1 基本概念和常识1.二进制思维2.文件类型3.文本文件的编码4.文件系统5.文件读写 13.1.2 Java文件概述1.流2.装饰器设计模式3.Reader/Writer4.随机读写文件5.File6.NIO7.序列化和反序列化 参考目录 13.1 文件概述 在本节&#xff0c;我们主要介…

Java文件操作

文章目录 1、文件的基本概念2、java文件操作2.1 File概述2.2 InputStream 和 FileInputStream2.3 OutputStream 和 OutputStreamWriter 1、文件的基本概念 平时说的文件一般都是指存储在硬盘上的普通文件&#xff0c;形如txt&#xff0c;jpg&#xff0c;mp4&#xff0c;rar等这…

Java 文件操作

Java 文件操作 引言1. 对文件的初步认识2. 绝对路径和相对路径 一、File 类File 类对应的方法创建一个文件测试一测试二测试三测试四测试五( 面试题 )测试六测试七 二、InputStream测试一try with resources 语法测试二测试三 三、OutputStream测试一测试二总结 四、案例案例1…

java文件

File File创建 1.根据路径构建FileFile file new File("d:\\1.txt");2.根据父目录文件子路径构建文件File parentFile new File("d:\\");String fileName "2.txt";File file new File(parentFile, fileName);3.父目录子路径构建String pare…

Java文件操作(超详细+代码示例)

Java文件操作 一、Java.io包1.1 File类1.2 Stream流&#xff08;字节流&#xff09;1.2.1 使用FileInputStream类1.2.2 使用FileOutputStream类1.2.3 小总结 1.3 Stream流&#xff08;字符流&#xff09;1.3.1 FileWriter类 与 BufferedWriter类使用1.3.2 FileReader类 与 Buff…

二、八大数据类型

在Java中有八种基本数据类型来存储数值、字符和布尔值&#xff1a; 2.1 整数型 整数型有byte(字节)、short(短整型)、int(整型)、long(长整型)四种。&#xff08;说明&#xff1a;可使用L或l后缀来声明长整型数值&#xff09; 以0开始的数值被解释为8进制数值&#xff1b;以…

Java 八大基本数据类型简述

java 的基本数据类型关系图 1、取值范围 类型默认值占用存储空间/字节范围byte01-127~128(-2的7次方到2的7次方-1)short02-32768~32767(-2的15次方到2的15次方-1)int04-2147483648~2147483647(-2的31次方到2的31次方-1)long08-9223372036854774808~9223372036854774807(-2的63次…

Java基础(一) 八大基本数据类型

自从Java发布以来&#xff0c;基本数据类型就是Java语言的一部分&#xff0c;分别是***byte, short, int, long, char, float, double, boolean***. 其中&#xff1a; 整型&#xff1a;byte, short, int, long 字符型&#xff1a;char 浮点型&#xff1a;float, double 布…

Java 中的八大基本数据类型、类型转换

目录 1. ♥常见的数据类型 2. ♥引用数据类型 3. ♥类型转换 4. ♥数值提升 5. ♥int 和 String 之间的相互转换 1. 基本数据类型 八大基本数据类型&#xff1a; 整型&#xff1a;byte、short、int、long浮点型&#xff1a;double&#xff08;双精度浮点型&#xff09;、…

Java基础:Java八大基本数据类型

一、背景。 这篇文章主要介绍了Java八大数据类型详细教程,本文通过图文并茂的形式给大家介绍的非常详细&#xff0c;对大家的学习或工作具有一定的参考借鉴价值&#xff0c;需要的朋友可以参考下。放假在家里休息&#xff0c;闲来无事&#xff0c;想巩固巩固自己的基础知识。J…

Java八大基本数据类型

前言&#xff1a;做一下笔记。 1.Java基本数据类型图 2.Java基本数据类型 整数类型&#xff1a;byte&#xff0c;1字节&#xff0c;8位&#xff0c;最大存储数据量是255&#xff0c;存放的数据范围是-128~127之间。整数类型&#xff1a;short&#xff0c;2字节&#xff0c;16…

好用网站推荐

说明 整理一下常用的网站&#xff0c;其中包括学习、素材、教学视频、一些优秀的论坛等网站&#xff0c;并推荐给大家大家按需获取 首先推荐一些非常好的网站&#xff0c;网站百度就能搜到&#xff1a;知乎&#xff0c;轻单&#xff0c;果壳&#xff0c;花瓣&#xff0c;电子发…

c++好用的网站

目录 洛谷www.luogu.com.cn 有道小图灵https://oj.youdao.com/csp 维基https://oi-wiki.org/ 信奥赛一本通http://ybt.ssoier.cn:8088/index.php 1&#xff0c;洛谷 他的网址是www.luogu.com.cn。 这是一个好用的刷题网站&#xff0c;题库里有大约有2000多道题。 洛谷有题…

有哪些好用的搜索引擎网站推荐?

分享一些私藏已久的搜索引擎&#xff0c;个个都十分强大&#xff0c;一起来看看吧&#xff01; 01.秘迹搜索 这是一款无敌有良心、无敌安全的搜索引擎&#xff0c;不会收集私人信息&#xff0c;保护私隐&#xff0c;没有Cookie&#xff0c;并且秘迹搜索聚合了百度、360、Bing…

分享一些冷门好用的网站和软件

分享一&#xff1a;UZER UZER是一个功能强大的云端应用空间&#xff0c;可以帮助您将所有的文件和应用程序都集中在一个地方&#xff0c;让您随时随地轻松访问。 以下是它的主要特点&#xff1a; 云存储&#xff1a;UZER提供大量的云存储空间&#xff0c;让您可以安全地存储…

网站分享:7个非常好用的电子书网站

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、 C#、 Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&…