简介:
从外部储存或者其他程序读数数据为输入,将结果写到外部内存或者写到别的程序中为输出。java.io包提供大量的流类,所有的输入流都是抽象类InputStream(字节输入流)或者抽象类Read(字符输入流)的子类,而所有的输出流都是抽象类OutputStream(子节输出流)或者抽象类write(字符输出流)的子类。
File类
File类主要用来获取文件本身的一些信息,不涉及对文件的读写操作。创建一个File对象的三个构造方法:
1:File(String filename)
2:File(String driectoryPath,String filename)
3:File(File dir,String name)
/*其中filename是文件的名字,directoryPath是文件的绝对路径,dir为一个目录。创建的文件与当前程序
在同一个目录中。
1:文件的属性
File一些常用方法:
1:public String getName() //获取文件的名字
2: public boolean canRead() //判断文件是否可读
3: public boolean canWrite() //判断文件是否可写
4: public boolean exists() //判断文件是否存在
5: public long length() ///获取文件的长度(单位是字节)
6: public String getAbsolutePath() //获取文件的绝对路径
7: public String getParent() //获取文件的父目录
8: public boolean isFile() //判断文件是否是一个普通文件
9: public isDirectory() //判断文件是否是一个目录
10: public boolean isHidden() //判断文件是否隐藏
11: public long lastModified() //获取文件的最后修改时间(毫秒数从1970年午夜计算)
例如:
Test_main.java
import java.io.File;
import java.io.IOException;
public class Test_Main {
public static void main(String[] args) {
File f=new File("C:\\","hello.java");
System.out.println(f.getName()+"是可读的吗"+f.canRead());
System.out.println(f.getName()+"的长度"+f.length());
System.out.println(f.getName()+"的绝对路径"+f.getAbsolutePath());
File file=new File("1.txt") ;
System.out.println("在当前路径下创建新文件:"+file.getName());
if(!file.exists())
{
try
{
file.createNewFile();
System.out.println("创建成功");
}
catch (IOException exp)
{
}
}
}
}
2:目录
File可以调用方法public boolean mkdir()
来创建一个目录,创建成功返回true;
当File对象时一个目录时,也可以调用下列方法列出该目录下的文件和子目录:
1:public String[] list() //用字符串的形式返回目录下的全部文件
2:public File[] listFile() //用file对象的形式返回全部文件
3:public String[] list(FilenameFilter obj) //以字符串的形式返回目录下的指定类型的所有文件。
4:public File[] listFiles(FilenameFilter obj) //用File对象的形式返回指定类型的文件。
/*上面的FilenameFilter是一个接口,接口中有一个方法如下*/
public boolean accept(File dir,String name)
3:文件的创建与删除
创建:
1:File(String filename)
2:File(String driectoryPath,String filename)
3:File(File dir,String name)
删除:
file.delete();
4:运行可执行文件
当需要运行一个可执行文件的时候,可以使用Runtime类。
首先声明一个Runtime对象:
Runtime rc
然后调用该类的方法getRuntime()
创建这个对象
rc=Runtime.getRuntime()
最后该对象调用exec(String command)
方法打开本地机器的可执行文件。
2:文件的字节输入流
使用输入流通常包括四个步骤:
- 设定输入流的源
- 创建指向源的输入流
- 让输入流读取源中的数据
- 关闭输入流
1:构造方法
可以使用下面两个构造方法指向文件的输入流:
FileInputStream(String name) //通过文件名称指定
FileInputStream(File file) //通过file对象来指定
例如:
FileInputStream in=new FileInputStream("1.txt") ;
或者
File f=new File("1.txt");
FileInputStream in=new FileInputStream(f);
【注】程序必须在try-catch语句中的try快部分创建输入流,在catch快检测并处理异常。
2:使用输入流读取字节
建立好输入流后,就可以调用从父类继承的read该方法顺序的读取文件,只要不关闭就可以顺序的读取。read方法有以下几种形式。
1: int read() //从源中读取单个字节的数据,该方法返回字节值(0-255)的一个整数。
2: int read(byte b[]) //读取b.length个字节到字节数组b中,
3: int read(byte b[],int off,int len) //读取len长度的字节到字节数据。off指定读取位置。
3:关闭流
调用close() 方法可以关闭输入流。
例如:
import java.awt.event.InputEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Test_Main {
public static void main(String[] args) {
int n=-1;
byte [] a=new byte[100];
try{
File f=new File("1.txt"); //指定输入流的源
FileInputStream in=new FileInputStream(f); //创建指向源的输入流
while ((n=in.read(a,0,n))!=-1) //输入
{
String s=new String(a,0,n);
System.out.print(s);
}
in.close(); //用完关闭
}catch (IOException e)
{
System.out.println("文件写入有错:"+e);
}
}
}
3:文件字节的输出流
使用输出流通常包括四个步骤:
- 给出输出流的目的地
- 创建指向目的地的输出流
- 让输出流把数据写入目的地
- 关闭输出流
1:构造方法
可以使用下面两个构造方法完成对输出流的构建:
FileOutputStream(String name) //以文件名称
FileOutputStream(File file) //以文件对象。
【注】:如果输出源文件不存在,Java会自己创建一个新文件,如果是已经存在的文件Java会刷新此文件使其长度为0;
同样程序必须在try-catch语句中的try快部分创建输入流,在catch快检测并处理异常。
2:使用输出流写字节
创建号输出流后,文件字节流就可以调用从父类继承的write方法顺序的写文件,常用的write方法如下:
1:void write(int n) //向目的地写入单个字节
2:void write(byte b[]) //向目的地写入一个字节数组
3:void write(byte b[],int len,int pos) //从给起始位置pos的字符数组取出长为len的数据写入目的地
4:void close() //关闭输出流。
4:文件字符的输入、输出流
文件字节的输入输出流去处理字符型数据时,会出现乱码的情况,针对这个情况,使用字符的输入输出流:FileReader
与FileWrite
。
其构造方法为:
FileReader(String filename)
FileReader(File file)
FileWrite(String filename)
FileWrite(File file)
FileWrite(String filename,boolean append)
FileWrite(File file,boolean append)
例如:
import java.io.*;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
public class Test_main {
public static void main(String[] args) {
File sourceFile=new File("a.txt");
File targetFile=new File("b.txt");
char c[]=new char[19];
try {
Writer out=new FileWriter(targetFile,true);
Reader in=new FileReader(sourceFile);
int n=-1;
while ((n=in.read(c))!=-1)
{
out.write(c,0,n);
}
}catch (IOException e)
{
System.out.println("Error"+e);
}
}
}
缓冲流
Java提供的缓冲流时BufferedReader与BufferedWriter类。有更好的读写能力。
构造方法:
BufferedReader(Reader in)
BufferedWrier(Writer out);
BufferReader流能够读取文本行,调用方法readLine即可。创建时只需要向BufferedReader传递一个reader对象即可:
FileReader inOne=new FileReader("Student.txt")
BufferedReader inTwo=BufferedReader(inOne)
然后inTwo就可以调用readLine() 方法读取文本行。
写入回行符的方法:newLine()
一般将缓冲流称作上层流,读数据时先将数据从底层流读到缓冲区(上层流)。
【注】关闭数据流时,应该先关闭缓冲流,不然会造成和数据的流失。
6:随机流
RandomAccessFile类创建的流称为随机流,既不是输入流的子类,也不是输出流的子类。它既可以作为输入流也可以作为输出流。
其构造方法如下:
RandomAccessFile(String name,String mode) //参数mode可以取值r(只读)、rw(读写)决定文件的读写权限。
RandomAccessFile(File file,String mode) //mode取值与上面一致。
需要注意的是,readLine() 方法在读取非ASCII字符时会出错(乱码),因此需要将得到的字符串用"iso-8859-1"重新编码。
具体步骤为:
1:读取
String str=in.readLine()
2:用"iso-8859-1"重新编码
byte b[]=str.getByte("iso-8859-1")
3:使用当前机器的默认编码将字节转换为字符串
String content=new String(b)
6:数组流
流的源和目的地可以是文件也可以是计算机的内存。
1:字节数组流
输入流:ByteArrayInputStream
输出流:ByteArrayOutputStraem
构造方法:
ByteArrayInputStream(byte[] buf)
ByteArrayInputStream(byte[] buf,int offset,int length)
ByteArrayOutputStraem(byte[] buf)
ByteArrayOutputStraem(byte[] buf,int offset,int length)
buf指定数组的全部字节单元,offset指定的起始位置开始存取长度为length个字节单元。
建立好输入输出流就可以调用方法,对字节流进行操作了,可以调用的方法有:
public int read() //从源中读出一个字节,返回的是字节值。
public int read(byte[]b,int off,int len) //返回指定位置长度的字节数
public int write()
public int write(byte[]b,int off,int len)
2:字符数组流
与字节数组流对应的是字符数组流:
CharArrayReader
CharArrayWriter
例如:
import java.io.ByteArrayOutputStream;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Test_Main {
public static void main(String[] args) {
try {
ByteArrayOutputStream outByte = new ByteArrayOutputStream(); //定义一个字节输出流
byte[] byteContent = "mid-autumn festival".getBytes(); //字符数组转换为字节数组
outByte.write(byteContent); //输出流指向源
ByteArrayInputStream inByte = new ByteArrayInputStream(outByte.toByteArray());
byte backByte[] = new byte[outByte.toByteArray().length];
inByte.read(backByte);
System.out.println(new String(backByte));
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 exp){};
}
}
7:数据流
DataInputStream和DataOutputStream类创建的对称为数据输入流和数据输出流不用关心数据的字节个数。
构造方法如下
DataInputStream(InputStream in) //创建一个数据输入流有参数in指定目的地
DataOutputStream(OutStream out) //创建的数据后输出流向指定一个参数out指定的底层输出流。
常用方法:
close()
readBoolean() //读取一个布尔值
readByte() //读取一个字节值
readChar()
readDouble()
readFloat()
readInt()
readLong()
readShort()
readUnsigndByte()
readUnsignedShort()
readUTF() //读取一个UTF字符串
skinBytes() //跳过给定数量的字节
writeBoolean(boolean v) //写入一个布尔值
writeBytes(String s)
writeChars(String s )
writeDouble(double s)
writeFloat(float f)
writeInt(int n)
writeLong(long l)
writeShort(short s)
writeUTF(String s)
例如:
import java.io.*;
public class Test_main {
public static void main(String[] args) {
File file=new File("1.txt");
try {
FileOutputStream fileOutputStream=new FileOutputStream(file);
DataOutputStream dataOutputStream=new DataOutputStream(fileOutputStream);
dataOutputStream.writeInt(100);
dataOutputStream.writeDouble(10.23);
dataOutputStream.writeChars("hello world");
dataOutputStream.writeBoolean(true);
} catch (IOException e) {
}
try {
FileInputStream fileInputStream=new FileInputStream(file);
DataInputStream dataInputStream=new DataInputStream(fileInputStream);
System.out.println(fileInputStream.readDouble());
System.out.println(fileInputStream.readBoolead());
char c='\0';
while( (c=fileInputStream.readChar())!='\0')
{
System.out.println(c);
}
} catch (IOException e){
}
}
}
8:对象流
对象流是InputStream与OutStream类的子类。
构造方法:
ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)
需要注意的是当使用对象写入或者读出对象时,要保证对象时是序列化的,所以类需要实现接口Serializable,实现此接口的类的对象就是序列化的,此接口不需要实现额外的方法。
9:文件对话框
文件对话框是一个选择文件的界面,javax.swing包中的JFileChooser类可以创建文件对话框。利用下面的构造方法创建初始不可见的有模式文件对话框,
JFileChooser()
然后可以调用下属两个方法:
showSaveDialog(Component a) //保存文件的对话框
showOpenDialog(Component a) /*打开文件的对话框,参数a 是null时对话框出现在屏幕正中央。如果不为
在组件a的前面居中显示。
当用户点击“确定”、“取消”、“关闭”时,文件对画框会自动消失。
方法的返回值为JFileChooser.APPROVE_OPTION
与JFileChooser_OPTION
当需要指定文件类型时,需要使用类FileNameExtensionFilter
先创建一个对象,例如:
FileNameExtensionFilter=new FileNameExtensionFilter("图像文件","jpg","gif")
然后文件对话框调用setFileFilter(FileNameExtensionFilter filter)
设置对话框默认打开或者显示文件类型为参数指定即可。
例如:
Test_main.java
public class Test_main {
public static void main(String[] args) {
WindowReader win=new WindowReader();
win.setTitle("使用文件对话框读写文件");
}
}
WindowReader.java
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
public class WindowReader extends JFrame implements ActionListener {
JFileChooser fileChooser; //文件对话框
JMenuBar jMenuBar;
JMenu jMenu;
JMenuItem itemSave,itemOpen;
JTextArea text;
BufferedReader in;
FileReader fileReader;
BufferedWriter out;
FileWriter fileWriter;
WindowReader(){
init();
setSize(300,400);
setVisible(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
void init(){
text=new JTextArea(10,10);
text.setFont(new Font("楷体",Font.PLAIN,28));
add(new JScrollPane(text),BorderLayout.CENTER);
jMenuBar=new JMenuBar();
jMenu=new JMenu("文件");
itemSave=new JMenuItem("保存文件");
itemOpen=new JMenuItem("打开文件");
itemSave.addActionListener(this);
itemOpen.addActionListener(this);
jMenu.add(itemSave);
jMenu.add(itemOpen);
jMenuBar.add(jMenu);
setJMenuBar(jMenuBar);
fileChooser=new JFileChooser();
FileNameExtensionFilter filter=new FileNameExtensionFilter("java文件","java");
fileChooser.setFileFilter(filter);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==itemSave)
{
int state=fileChooser.showSaveDialog(this);
if(state==JFileChooser.APPROVE_OPTION)
{
try {
File dir=fileChooser.getCurrentDirectory();
String name=fileChooser.getSelectedFile().getName();
File file=new File(dir,name);
fileWriter=new FileWriter(file);
out=new BufferedWriter(fileWriter);
out.write(text.getText());
out.close();
fileWriter.close();
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
}
}
else if(e.getSource()==itemOpen)
{
int state=fileChooser.showOpenDialog(this); //
if(state==JFileChooser.APPROVE_OPTION)
{
text.setText(null);
try
{
File dir=fileChooser.getCurrentDirectory();
String name=fileChooser.getSelectedFile().getName();
File file=new File(dir,name);
fileReader=new FileReader(file);
in=new BufferedReader(fileReader);
String s=null;
while ((s=in.readLine())!=null)
{
text.append(s+'\n');
}
in.close();
fileReader.close();
}
catch(IOException exp){}
}
}
}
}
9:带进度条的输入流
如果在读取文件时,希望可以看到存取的进度,就需要使用javax.swing包中提供的类ProgressMonitorInputStream,他的构造方法如下
ProgressMonitorInputStream(Component c,String s,InputStream)
/*其中第一个参数指定依赖的组件,可以为null,null时显示在屏幕正中央,s为进度条的提示文字,InputStream为输入流。
例如:
import javax.swing.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Test_main {
public static void main(String[] args) {
byte b[]=new byte[30];
try {
FileInputStream inputStream=new FileInputStream("3.txt");
ProgressMonitorInputStream inputStream1=new ProgressMonitorInputStream(null,"读取中...",inputStream);
ProgressMonitor p=inputStream1.getProgressMonitor();
while (inputStream.read(b)!=-1)
{
String s=new String(b);
System.out.println(s);
Thread.sleep(1000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
10:文件锁
Java提供FileLock类与FileChannel类对文件进行上锁。
具体步骤为:
1:先试用类RandomAccessFile
建立一个一个输入或者输出流。只有此类建立的输入输出流可以对文件进行上锁。
RandomAccessFile input=new RandomAccessFile("1.txt","rw") //建立输入流,必须为rw型
2:输入流调用方法getChannel()方法获得一个连接到底层文的FileChannel对象(信道)
FileChannel channel=input.getChannel()
3:信道调用FileLock()或者lock()方法对文件枷锁
FileLock lock=channel.tryLock()
【注】加锁的文件不能被其他程序访问,需要通过release()
方法对其进行解锁。
lock.release()