程序在运行期间,可能需要从外部存储媒介或者其他程序中读入数据。这就需要输入流。
程序通过输入流读取和输入流相关的源(输入流的指向称之为源)里面的数据。
程序在运行期间,可能需要将产生的数据存入到程序之外的地方,这个时候就要是要输出流。
程序通过输出流把程序中产生的数据送入目的地。
1、File类的构造函数
File类对象主要用于获取文件自身的一些信息(文件所在目录、文件大小等等),但是不能用于操作文件内容。
下面看看File类的构造方法:
File(String filename); //filename是文件的名,如果直接输入名字(比如1.txt)的话,那么就默认是相对路径
File(String directoryPath , String filename);//directoryPath是文件路径
File(File dir , String filename);//dir是目录,也就是一个文件夹
我们一般就用第一种就可以了。
2、文件的属性
下面列举File类常用的方法:
File类对象 | 常用方法 |
---|---|
public String getName() | 获取文件名字 |
public boolean canWrite() | 文件是否可写 |
public boolean canRead() | 文件是否可读 |
public boolean exists() | 判断文件是否存在 |
public long length() | 获取文件长度(单位是字节) |
public String getAbsolutePath() | 获取文件的绝对路径 |
public String getParent() | 获取文件的父目录 |
public boolean isFile() | 判断文件是一个普通文件而不是文件夹 |
public boolean isDirectory() | 判断文件是文件夹而不是一个普通文件 |
public long lastModified() | 获取文件最后一次被修改的时间 |
public void CreateNewFile() | 创建一个新的文件 |
public boolean delete() | 删除指定文件 |
下面就给一个简单的例子:
package cn.com;
import java.io.File;
import java.io.IOException;
public class Test
{
public static void main(String args[])
{
File file = new File("E:\\java\\GUI\\src\\cn\\com\\Test.java");
System.out.println(file.getName() + "是否存在:" + file.exists());
System.out.println(file.getName() + "是否可写:" + file.canWrite());
System.out.println(file.getName() + "是否可读:" + file.canRead());
System.out.println(file.getName() + "是否可写:" + file.canWrite());
System.out.println(file.getName() + "的长度为:" + file.length());
System.out.println(file.getName() + "的绝对路径:" + file.getAbsolutePath());
File file1 = new File("new.txt");
System.out.println("在当前目录下创建一个新的文件:" + file1.getName());
if(file1.exists()==false)
try
{
file.createNewFile();
System.out.println("创建成功");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
读者可以自己运行下看看效果。
3、文件的目录
创建目录:
public boolean mkdir() | 创建成功的话返回true;失败则返回false。注意,如果File对象本身就是所创建的目录的话那么也会创建失败 |
---|
输出目录下的所有文件名:
File类对象是目录的情况下,调用下面的方法:
File 对象 | 方法作用 |
---|---|
public String[] list() | 以字符串的形式返回该目录下的所有文件和子目录(这个时候返回的就是对于的文件名了) |
public File[] listFiles() | 以File对象的形式返回该目录下的所有文件和子目录 |
有的时候需要输出指定目录下的指定类型的文件(.txt,.java等),这个时候需要调用下列函数:
File 对象 | 方法作用 |
---|---|
public String[] list(FilenameFilter obj) | 以字符串的形式返回该目录下指定类型的所有文件(这个时候返回的就是对于的文件名了) |
public Fiel[] listFiles(FilenameFilter obj) | 以File对象的形式返回该目录下指定类型的所有文件 |
但是上面两种方法的FilenameFilter 是一个接口,它里面有一个方法:
public boolean accept(File dir , String name);
当File类对象是一个目录dirFile的时候,dirFile调用list(FilenameFilter obj)方法时,实现了FilenameFilter 接口的类调用accept()方法,其中dir参数是当前的总目录,参数name就是该目录下的一个文件名。当list返回true的时候就会将名字为name的文件存到对应的数组中。
下面就来看看例子:
package cn.com;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
public class Test
{
public static void main(String args[])
{
//获取当前文件夹下所有以.java作为扩展名的文件名
File file = new File("E:\\java\\GUI\\src\\cn\\com");
//调用list方法获取该文件夹下所有以.java作为扩展名的文件名
String[] filenames = file.list(new FilenameFilter()
{
//重写接口中的方法
public boolean accept(File dir , String name)
{
return name.endsWith(".java");
}
});
System.out.println(file.getName() + "文件夹下的所有.java文件名为:");
for (String str : filenames)
System.out.println(str);
}
}
4、运行可执行文件
要执行一个本地可执行文件的时候,使用Runtime类就行。直接调用exec()方法就行。
下面看看例子:
package cn.com;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
public class Test
{
public static void main(String args[])
{
try
{
Runtime run = Runtime.getRuntime(); //获取Runtime类对象
//运行桌面的Nodepad++
File file = new File("D:\\Notepad++\\notepad++.exe");
run.exec(file.getAbsolutePath());
//运行桌面的有道词典
run.exec("C:\\Users\\86183\\AppData\\Local\\youdao\\dict\\Application\\YoudaoDict.exe");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
1、输出:
对文件写入的操作比较简单,直接使用FileOutputStream类就行(以字节为单位写)。它是OutputStream类的子类。
构造方法:
FileOutputStream(String name)
FileOutputStream(File file)
其中参数name 和 file指定的文件就是一开始提到的目的地。
注意:如果目的地文件不存在,系统会自动创建一个相应的文件;要是文件存在的话,就会从头开始写(也就是说会清空一开始的文件内容)。
不过要说一点:和C不同的是,Java提供了可以设置是否具有刷新功能的方法:
FileOutputStream(String name , boolean append)
FileOutputStream(File file , boolean append)
当参数append为true时,就不会刷新源文件的内容,也就是从文件的末尾开始写。
下面就开始写字节到指定的文件了:使用的是write()方法(顺序写入):
FileOutputStream对象 | 方法 |
---|---|
void write(int n) | 写入单个字节 |
void write(byte b[]) | 写入一个字节数组 |
void write(byte b[] , int off , int len) | 从字节数组b中的off位置开始写入len个字节 |
void close() | 关闭输出流 |
---|
在写的过程中,为了提高CPU的效率,程序通常先写到内存中(在内存中创建一个缓冲区),然后调用close()方法后系统就会将该内存中的数据洗到对应的磁盘里面。
下面看看具体的例子:
package cn.com;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
public class Test
{
public static void main(String args[])
{
File file = new File("C:\\Users\\86183\\Desktop\\1.txt");
byte a[] = "Hello , world".getBytes();
byte b[] = "Hello , world".getBytes();
try
{
//建立输出流,将他和要写入的文件绑定
OutputStream out_file = new FileOutputStream(file , false);
//开始写数据进文件
out_file.write(a);
//写入完毕,关闭输出流
out_file.close();
/*
//重新打开输出流————刷新的形式写
out_file = new FileOutputStream(file , false);
out_file.write(b);
out_file.close();*/
//重新打开输出流————不刷新的形式写
out_file = new FileOutputStream(file , true);
out_file.write('\n');
out_file.write(b);
out_file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("文件操作完毕");
}
}
2、输入:
输入和输出形式基本差不多,只是用的函数不同。这里也简单介绍下:
对文件读取的操作比较简单,直接使用FileInputStream类就行(以字节为单位读)。它是InputStream类的子类。
构造方法:
FileInputStream(String name)
FileInputStream(File file)
下面就开始读取指定的文件了:使用的是read()方法(顺序读取):
FileInputStream对象 | 方法 |
---|---|
int read() | 读取单个字节,返回读取字节的字节值(0—255的整数);读取失败返回-1 |
int read(byte b[]) | 读取byte.length个字节到b数组,如果没那么多的字节,就读取全部字节。返回实际读取到的字节数;到文件末尾返回-1 |
int read(byte b[] , int off , int len) | 读取len个字节到b数组中;参数off指定b数组开始存放读取到的数据的起始位置 |
void close() | 关闭输入流 |
---|
下面看看例子:
package cn.com;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Test
{
public static void main(String args[])
{
File file = new File("E:\\java\\GUI\\src\\cn\\com\\Test.java");
byte a[] = new byte[(int) file.length()];
try
{
//建立输出流,将他和要写入的文件绑定
InputStream read_file = new FileInputStream(file);
//开始写数据进文件
read_file.read(a);
//写入完毕,关闭输出流
read_file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(new String(a , 0 , a.length));
}
}
上面提到的是字节输入输出流。以字节为单位的话不能很好的处理Unicode字符。如:一个汉字占连个字节,那你读取一个字节的话就会发生错误。
字符输入输出流和字节输入输出流很类似,这里不再详细介绍了。
FileReader——文件字符输入流,父类是Reader
FileWriter——文件字符输出流,父类是Writer
下面看看构造方法:
FileReader(String filename)
FileReader(File file)
FileWriter(String filename)
FileWriter(File file)
FileWriter(String filename , boolean append)
FileWriter(File file , boolean append)
下面直接看看例子:
package cn.com;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Test
{
/*
* 从1.txt文件中读取数据写入2.txt文件中
*/
public static void main(String args[])
{
File file1 = new File("C:\\Users\\86183\\Desktop\\1.txt");
File file2 = new File("C:\\Users\\86183\\Desktop\\2.txt");
char a[] = new char[100]; //存储文件1中的数据
try
{
//创建文件字符输入输出流
Reader in_file = new FileReader(file1);
Writer out_file = new FileWriter(file2 , false);
in_file.read(a);
out_file.write(a);
in_file.close();
//out_file.flush();
out_file.close();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("文件操作完毕");
}
}
注意上面有一句代码:
out_file.flush();
这里单独解释下:
对于Write流,write方法首先会将数据写入缓冲区,每当缓冲区满了之后里面的内容就会自动写入目的地,如果关闭流的话,缓冲区的内容就会被立即写入目的地。但是当调用flush()方法后,缓冲区里的内容就会被写入目的地。
BufferedReader和BufferedWriter类创建的对象称之为缓存输入输出流。
BufferedReader的源是FileReader,BufferedWriter的目的地是FileWriter。
他们的构造方法:
缓冲输入输出流 | 构造方法 |
---|---|
BufferedReader | BufferedReader(Reader in); |
BufferedWriter | BufferedWriter(Writer out); |
BufferedReader 对象有一个方法readLine()可以按行读取文件。这是之前的文件字节和文件字符输出流所办不到的。
同理,BufferedWriter对象使用write(String s , int off , int len);方法写入数据到目的地。
BufferedWriter对象还有一个newLine()方法向文件写入一个回车符。
下面看看具体的例子:
package cn.com;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
public class Test
{
public static void main(String args[])
{
/*
* 借助缓冲输入输出流输出1.txt文件的内容并写入2.txt
*/
File file1 = new File("C:\\Users\\86183\\Desktop\\1.txt");
File file2 = new File("C:\\Users\\86183\\Desktop\\2.txt");
try
{
Reader read_file = new FileReader(file1); //创建文件字符输入流
Writer write_file = new FileWriter(file2); //创建文件字符输出流
BufferedReader buff_read_file = new BufferedReader(read_file);//创建缓冲输入流
BufferedWriter buff_writer_file = new BufferedWriter(write_file);//创建缓冲输出流
//开始读取文件————按行读取
char a[] = new char[(int)file1.length()]; //创建一个可以容纳文件1.txt全部内容的缓冲区
String str = null;
while((str = buff_read_file.readLine())!=null)
{
System.out.println(str);
buff_writer_file.write(str); //向2.txt写入数据
buff_writer_file.newLine();
}
buff_read_file.close();
buff_writer_file.close();
}
catch(Exception e)
{
System.out.println(e);
}
System.out.println("文件操作完成");
}
}
RandomAccessFile类对象创建的流既可以是输入流也可以是输出流,这个取决于它的构造函数的一个参数值。
随机流RandomAccessFile构造方法 | 参数说明 |
---|---|
RandomAccessFile(String name , String mode) | name是文件的名字,mode只能取值"r"——只读或者"rw"——可读可写 |
RandomAccessFile(File name , String mode) | name是文件的名字,mode只能取值"r"——只读或者"rw"——可读可写 |
注意:随机流指向文件时,不会刷新文件,而且他还有对应的设置读写位置的方法seek(long a:参数a是距离文件开头的字节数。另外,还可以调用getFilePointer()方法获取文件当前读写位置
注意:当RandomAccessFile对象调用readLine()方法读取一行文本时,如果该行文本有非ASCII字符(如汉字)的话,必须将字符串用"iso-8859-1"重新编码存放到字节数组中,然后系统会自动转换输出。
看下面的例子:
package cn.com;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Test
{
public static void main(String args[])
{
File file1 = new File("C:\\Users\\86183\\Desktop\\1.txt");
try
{
RandomAccessFile read_file = new RandomAccessFile(file1 , "r");
String str = null;
try
{
while((str=read_file.readLine())!=null)
{
byte b[] = str.getBytes("iso-8859-1");
System.out.println(new String(b));
}
read_file.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
System.out.println("文件操作完成");
}
}
RandomAccessFile 的方法太多,这里就不列举了。读者可以自己查阅。
上面提到的源和目的地都是文件。其实源和目的地也可以是数组。
字节数组流
字节数组输入流 | 构造方法 |
---|---|
ByteArrayInputStream | ByteArrayInputStream(byte[] buf) ,参数buf就是源 |
ByteArrayInputStream | ByteArrayInputStream(byte[] buf , int offset , int length) ,参数buf是源,length参数指定读取的字节长度,参数offset指定从源的第几个字节开始读取 |
字节数组输入流 | 主要方法 |
---|---|
ByteArrayInputStream | read() 从源中读取一个字节 |
ByteArrayInputStream | read(byte[] b , int off , int length) 从源中读取length个字节,将读取的字节放到b数组中,参数off设定b开始存储的位置 |
字节数组输出流 | 构造方法 |
---|---|
ByteArrayOutputStream | ByteArrayOutputStream() ,默认指向32字节的缓冲区,当缓冲区写满时会自动增加 |
ByteArrayOutputStream | ByteArrayOutputStream(int size) ,参数size指定缓冲区大小,当缓冲区写满时会自动增加 |
字符数组流
和上面对应的两个类是CharArrayReader和CharArrayWriter
下面直接看看具体例子吧:
package gen;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
public class Example_10
{
public static void main(String[] args)
{
ByteArrayInputStream byte_array_input; //字节数组输入流
ByteArrayOutputStream byte_array_output; //字节数组输出流
CharArrayReader char_array_read; //字符数组输入流
CharArrayWriter char_array_write; //字符数组输出流
byte[] array_byte_content = "Hello , world,我是谁?".getBytes(); //源 字节数组
char[] array_char_content = "I am come from China".toCharArray(); //源 字符数组
try
{
byte_array_input = new ByteArrayInputStream(array_byte_content);//将 字节数组输入流 和 流 关联
byte_array_output = new ByteArrayOutputStream();
byte[] array = new byte[array_byte_content.length];
byte_array_input.read(array); //读取源中的数据到array
byte_array_output.write(array); //读取array中的数据到缓冲区
System.out.println(new String(byte_array_output.toByteArray()));//输出缓冲区内容
char_array_read = new CharArrayReader(array_char_content); //将 字符数组输入流 和 流 关联
char_array_write = new CharArrayWriter();
char[] array1 = new char[array_char_content.length];
char_array_read.read(array1); //读取源中的数据到array
char_array_write.write(array1); //读取array中的数据到缓冲区
System.out.println(new String(char_array_write.toCharArray())); //输出缓冲区内容
}
catch(Exception e)
{
}
}
}
DataOutputStream和DataInputStream类创建的对象是数据输出流和数据输入流。
它允许程序按着和机器无关的风格读取Java原始数据,换句话说,读取这个数值的时候不需要去关心这个数值是多少字节。
下面看看构造函数
数据输出流 | 构造函数 |
---|---|
DataOutputStream | DataOutputStream (OutnputStream out),创建一个指向底层流out的数据输出流 |
数据输入流 | 构造函数 |
---|---|
DataInputStream | DataInputStream(InputStream in),创建一个指向底层流in的数据输入流 |
他们的具体实例方法这里就不一一列举了,下面直接看看具体代码吧:
package gen;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example_10
{
public static void main(String[] args)
{
DataOutputStream data_output_stream; //创建 数据输出流
DataInputStream data_input_stream; //创建 数据输入流
File file = new File("C:\\Users\\86183\\Desktop\\1.txt");
try
{
if (file.exists())
file.createNewFile();
data_output_stream = new DataOutputStream(new FileOutputStream(file));
//向文件输出数据
data_output_stream.writeInt(100);
data_output_stream.writeDouble(4.14);
data_output_stream.writeBoolean(true);
data_output_stream.writeChars("Hello , worlddd");
data_output_stream.close(); //关闭数据输出流
data_input_stream = new DataInputStream(new FileInputStream(file));
System.out.println(data_input_stream.readInt());
System.out.println(data_input_stream.readDouble());
System.out.println(data_input_stream.readBoolean());
char c='\0';
while ((c =data_input_stream.readChar() )!='\0')
System.out.print(c);
data_input_stream.close(); //关闭输入流
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
再来看一个关于字符串加密的例子:
package gen;
public class Encry_And_Dec
{
//解密算法
public String Encrypt(String sourceString , String password)
{
char[] p = password.toCharArray();
char[] s = sourceString.toCharArray();
int p_length = p.length;
int s_length = s.length;
//开始加密
for (int k = 0 ; k<s_length ; k++)
{
int mima = s[k] + p[k % p_length];
s[k] = (char)mima;
}
return new String(s);
}
//解密算法
public String Decrpty(String sourceString , String password)
{
char[] p = password.toCharArray();
char[] s = sourceString.toCharArray();
int p_length = p.length;
int s_length = s.length;
//开始解密
for (int k = 0 ; k<s_length ; k++)
{
int mima = s[k] - p[k % p_length];
s[k] = (char)mima;
}
return new String(s);
}
}
package gen;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Example_10
{
public static void main(String[] args)
{
String str = "今天九点在城外集合";
Encry_And_Dec person = new Encry_And_Dec();
String password = "hahaha"; //加密的密码
File file = new File("C:\\Users\\86183\\Desktop\\1.txt");
//获取密文
String serect = person.Encrypt(str, password);
DataOutputStream data_output_stream; //创建 数据输出流
DataInputStream data_input_stream; //创建 数据输入流
try
{
if (file.exists())
file.createNewFile();
data_output_stream = new DataOutputStream(new FileOutputStream(file));
data_output_stream.writeUTF(serect);
System.out.println("密文为:" + serect);
data_input_stream = new DataInputStream(new FileInputStream(file));
//读取密文
System.out.println("原文为:" + person.Decrpty(data_input_stream.readUTF(), password));
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
ObjectOutputStream和ObjectInputStream类创建的对象分别是对象输出流和对象输入流。
看看构造方法:
对象输出流 | 构造函数 |
---|---|
ObjectOutputStream | ObjectOutputStream(OutputStream in) |
对象输入流 | 构造函数 |
---|---|
ObjectInputStream | ObjectInputStream(InputStream in) |
他们分别调用writeObject和readObject方法写入和读取对象。
这里强调一点:使用对象流读写对象的时候,要保证对象是序列化的。只需要在编写类的时候实现Serializable接口就行。该接口的方法对外不可见,我们不需要去实现里面的具体方法。
下面就看看例子吧:
package gen;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test
{
public static void main(String args[])
{
TV changhong = new TV();
changhong.setName("长虹电视");
changhong.setPrice(5600);
try
{
//创建 对象输出流
ObjectOutputStream objectOut = new ObjectOutputStream(new FileOutputStream("C:\\Users\\86183\\Desktop\\mytv.txt"));
objectOut.writeObject(changhong); //将changhong对象写入文件
objectOut.close();
//创建对象输入流
ObjectInputStream objectIn = new ObjectInputStream(new FileInputStream("mytv.txt"));
TV xinfei = (TV)objectIn.readObject(); //从文件读取一个对象到内存
xinfei.setPrice(6000);
System.out.println("changhong的名字:" + changhong.getName() +",changhong的价格:" + changhong.getPrice() );
System.out.println("xinfei的名字:" + xinfei.getName() +",xinfei的价格:" + xinfei.getPrice() );
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class TV implements Serializable
{
private String name;
private double price;
public void setName(String name)
{
this.name = name;
}
public void setPrice(double price)
{
this.price = price;
}
public String getName()
{
return this.name;
}
public double getPrice()
{
return this.price;
}
}
看下面的例子:
A a = new A();
A b = a;
这个时候a和b指向同一个对象,如果修改a或者b中的任意一个,那么a和b都会改变,因为他们指向同一个对象。那么能不能得到a对象的一个复制品呢?当然是可以的,这里就要用到对象克隆了。
上面提到的对象流就是一个解决方法:将一个对象写入文件,然后用对象输入流从文件中读取这个对象。这样就完成的对象的克隆。
但是文件操作的话会很慢,要想快速的得到一个对象的克隆,我们可以将对象写入内存而不是写入文件。这就需要我们前面提到的数组流。
将数组流作为对象流的底层流就可以完成。
下面看看例子吧:还是上面的例子,这里我们改为用内存过度:
package gen;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test
{
public static void main(String args[])
{
TV changhong = new TV();
changhong.setName("长虹电视");
changhong.setPrice(5600);
try
{
ByteArrayOutputStream byte_write = new ByteArrayOutputStream(); //字节数组输出流
ObjectOutputStream objectOut = new ObjectOutputStream(byte_write); //创建对象输出流——输出到内存
objectOut.writeObject(changhong); //将changhong对象写入文件
objectOut.close();
//创建对象输入流
ByteArrayInputStream byte_read = new ByteArrayInputStream(byte_write.toByteArray()); //字节数组输入流
ObjectInputStream objectIn = new ObjectInputStream(byte_read);
TV xinfei = (TV)objectIn.readObject(); //从文件读取一个对象到内存
xinfei.setPrice(6000);
System.out.println("changhong的名字:" + changhong.getName() +",changhong的价格:" + changhong.getPrice() );
System.out.println("xinfei的名字:" + xinfei.getName() +",xinfei的价格:" + xinfei.getPrice() );
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class TV implements Serializable
{
private String name;
private double price;
public void setName(String name)
{
this.name = name;
}
public void setPrice(double price)
{
this.price = price;
}
public String getName()
{
return this.name;
}
public double getPrice()
{
return this.price;
}
}
文件对话框(文件选择器)是一个选择文件的界面。
JFileChooser类的对象可以创建文件对话框。
然后该类的对象可以调用下面两个方法显示文件对话框:
用户单击文件对话框上的打开或者取消时,对应的返回值分别是:JFileChooser.APPROVE_OPTION和JFileChooser.CANCEL_OPTION
如果希望文件对话框可以只打开你要的文件的话,可以让文件对话框对象调用
**setFileFilter()**方法。比如说:
JFileChooser fileChoose = new JFileChooser(); //创建文件对话框
FileNameExtensionFilter filter1 = new FileNameExtensionFilter("java文件" , "java");
FileNameExtensionFilter filter2 = new FileNameExtensionFilter("文本文件" , "txt");
fileChoose.setFileFilter(filter1);
fileChoose.setFileFilter(filter2);
这样一来可以加快选择
下面就给出一个综合一点的例子:(点击即可)
使用文件对话框保存和读取文件
这里还给大家提供一个JFileChooser有关的应用:
Java小程序——文件选择器,超实用
有关JFileChooser的具体用法请参考:JFileChooser文件选择器类详解
有的时候会出现几个程序处理一个文件,这个时候有可能会出现混乱。Java随后就引入了文件锁的概念。
我们在使用文件输入输出流的时候就可以配合使用文件锁。
文件被锁定之后就不不能被其他程序操作。
下面结合RandomAccessFile来看看具体使用。
下面看看具体使用步骤:
下面给出实例:
package cn.com;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class WindowFileLock extends JFrame
{
private JButton button;
private JTextArea textshow;
private RandomAccessFile random_file;
private FileLock lock;
private FileChannel chanel;
private boolean ifChage = false;
public static void main(String[] args)
{
WindowFileLock win = new WindowFileLock();
}
public WindowFileLock()
{
init();
}
public void init()
{
JPanel nor_pan = new JPanel();
try
{
File file = new File("C:\\Users\\86183\\Desktop\\1.txt");
this.random_file = new RandomAccessFile(file,"rw");
this.chanel = this.random_file.getChannel();
this.lock =this.chanel.tryLock(); //对文件加锁
}
catch (Exception e)
{
e.printStackTrace();
}
//初始化按钮
this.button = new JButton("读取一行");
this.button.setFocusPainted(false);
this.button.setPreferredSize(new Dimension(90 , 30));
nor_pan.add(this.button);
//初始化文本区
this.textshow = new JTextArea();
this.textshow.setFont(new Font("华文行楷" , Font.PLAIN , 20));
JScrollPane cen_pan = new JScrollPane(this.textshow);
this.button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
do_button_actionPerfered(e);
}
});
this.add(nor_pan , BorderLayout.NORTH);
this.add(cen_pan);
//设置窗体属性
this.setTitle("文件锁应用");
this.setExtendedState(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 500);
this.setVisible(true);
}
private void do_button_actionPerfered(ActionEvent e)
{
/*
* 读取一行后就对文件加锁
*/
if (e.getSource() == this.button)
{
if (this.ifChage == true)
{
JOptionPane.showMessageDialog(this, "文件已经读取完毕,无法再读取",null ,JOptionPane.WARNING_MESSAGE);
return;
}
try
{
this.lock.release(); //解锁
String str = this.random_file.readLine();
this.textshow.append(str + "\n");
if (str != null)
this.lock = this.chanel.tryLock(); //读取完毕后立马加锁
else if (str == null)
{
this.textshow.append("文件读取完毕\n");
this.random_file.close();
this.ifChage = true;
}
}
catch(Exception e1)
{
e1.printStackTrace();
}
}
}
}
花了一些时间,将Java的I/O流做了一个简单的整理,作为以后的复习资料。
这里也和大家分享下,共同学习。
如果这篇博客对你有帮助的话就请点赞吧~~~~