文件的输入与输出
对文件的操作总的来说分为两部分:对文件的操作,对流的操作,流的操作实在对文件操作的基础上建立起来的。
1.File类
在使用时导入io包,file类只能用来表示文件信息,不能用于文件的访问。
具体就是常用的File类下的方法:
方法名称 | 返回类型 | 具体功能 |
File(String path); | path是路径名 | |
File(Stirng path,String name); | path路径下的name文件 | |
File(File dir,String name); | dir表示的是路径名 | |
getName(); | String | 得到文件名(不是路径) |
getPath() | String | 得到路径 |
getAbsolutePath(); | String | 得到一个文件的绝对路径 |
getParent(); | String | 得到上一级的目录名称 |
exists(); | boolean | 测试文件是否存在,存在返回true否则则返回false |
isFile() | boolean | 测试文件是否是文件,是返回true,不是返回false |
isDirectory() | boolean | 测试文件是否是目录,是返回true,不是返回false |
length() | long int | 得到文件的长度(以字节为单位) |
delete() | boolean | 删除文件 |
mkdir() | boolean | 创建文件夹 |
list() | String | 列出当前文件夹下的文件 |
package test01;
import java.io.*;
import java.util.Iterator;
public class t01 {
//实例化file类
public static void main(String[] args) throws IOException{
File file=new File("demo");
if(!file.exists())
file.createNewFile();//如果不存在则创建
String path1="D:\\eclipse\\my java\\test01\\src\\test01";//因为\是转义字符,所以要用\\
File parentfile1=new File(path1);
String[] name=parentfile1.list();//列出所有子文件存入字符串中
for(String str:name)
{
System.out.println(str);
}
}
}
InnerClassTest.java
Innertest.java
Intest.java
Manager.java
Sontest.java
t01.java
test02.java
2.RandomAccessFile类
RandomAccessFile类是对文件随机访问文件的读取和写入,该随机访问文件类似于存储在文件系统中的一个庞大的数组,存取文件的过程中伴随着文件指针的移动,该文件指针可以通过getPointer方法获取,并通过seek方法设置
RandomAccessFile(String name,String mode) | name是操作文件的名称,mode是打开方式,“r”表示可读“w”表示可写“rw”表示读写 |
RandomAccessFile(File name,String mode) | 参数是File类 |
long getFilePointer() | 用于得到当前文件指针 |
void seek(long pos) | 设置文件指针的到指定位置 |
int skipBytes(int n) | 设置文件只针向前向前移动指定的位置 |
3.字符流
- 字符输入输出流是Reader和Writer,Reader是输入流的基类,Writer是输出流的基类。Readerd的子类有FileReader,BufferedReader。
- Reader是java中所有字符输入流的父类,该类是抽象类,所有在使用中不能抽象化该类。
- Writer是java中所有字符输出流的父类,该类是抽象的,不能实例化该类。
- flush();//清空刷新流
- 操作完毕后,记得关闭流。
package test01; import java.io.*; import java.util.Iterator; public class t01 { public static void main(String[] args) throws IOException{ //向文件中写入数据 File file=new File("demo2"); if(file.exists()) System.out.println("文件已经存在"); else{ file.createNewFile();System.out.println("创建新文件");} //向文件中写入 FileWriter writer=new FileWriter(file); writer.write("today is fun"); writer.flush();//刷新流 writer.close(); FileReader read=new FileReader(file); BufferedReader reader=new BufferedReader(read); String str1=reader.readLine(); reader.close(); read.close(); System.out.println(str1); } }创建新文件 today is fun
1.字符缓冲流,读写流
字符缓冲流是BufferedReader和BufferedWriter,缓冲区默认大小为8192个字符(并不是很大),在执行过程中不会直接执行成功,而是传入到缓冲区中,再调用方法读取。
BufferedReader(Reader in) | 以Reader对象in创建BufferReader,记住是以Reader对象不是File对象 |
BufferedReader(Reader in,int sz) | 通过sz指定缓冲区的大小 |
BufferedWriter(Writer out) | 通过Writer对象来创建BufferedWrier对象 |
BufferedWriter(Writer out,int sz) | sz指定缓冲区的大小 |
同样记住一点,无论什么流使用完之后都要关闭。
2.研究一下read(char)方法在字符流中的应用
这里的char相当于是一个缓冲区,当打开文件流的时候,系统从文件中读取文件,将文件的数据存储在内存中的char[]数组中,当输出的时候在从文件中输出(有了缓冲区的存在,系统读文件的时候就是比较快了)。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MyFile {
/**
* 测试带参数的read(char)方法。
*/
String path;//存储文件的路径
public void readFile(String name) throws IOException {
File file=new File(name);
FileReader read=new FileReader(file);//进行文件的读取工作
char[] ch=new char[5];//作为缓冲区暂时存储字符
while(read.read(ch)!=-1) {
System.out.println(new String(ch));
}
read.close();//关闭流
}
}
4.字节流
InputStream是所有字节输入流的超类,OutputStream所有输出流的超类,在他的派生类中要实现所有的抽象方法。
FileOutputStream是输出流的子类,使用这个流的特点是,如果该文件没有存在,则会创建该文件,如果存在,则会覆盖该文件---------(有时候真不知道是好还是坏)当然针对文件覆盖问题还有解决方案:
附加文件构造方法,第二个参数为true就表示:如果存在,则在文件末尾位置写入,如果不存则创建文件
(2)OutputStream中的方法flush是刷新流,输出缓冲区中的字符,以免产生错误
package test01;
import java.io.*;
import java.util.Iterator;
public class t01 {
public static void main(String[] args) throws IOException{
//向文件中写入数据
File file=new File("demo3");
if(file.exists()) System.out.print("文件已经存在");
FileOutputStream out=new FileOutputStream(file);
if(file.exists()) System.out.println("文件已经存在");
out.write(43);
out.close();
//读取文件
FileInputStream in=new FileInputStream(file);
int b= in.read();
System.out.println(b);
in.close();//关闭流
FileOutputStream out1=new FileOutputStream(file,true);//如果文件存在则打开,在文件末尾添加
out1.write(23);
out.close();
//读取文件到末尾
FileInputStream in1=new FileInputStream(file);
int bt;
while((bt=in1.read())!=-1)
System.out.println(bt);
in1.close();
}
}文件已经存在文件已经存在
43
43
23
FileIntputStream是输入流的子类,用来读取文件。
字符流读文件
在这次实验中,将创建Employee类,创建的时候用“|”分隔开来,读的时候整行读取,然后在用split将字符串分解开来,再存入数据中
package LearnStream;
public class Employee{
String name;
double salary;
int year,month,day;
public Employee() { }
public Employee(String name,double salary,int year,int month,int day) {
this.name=name;
this.salary=salary;
this.year=year;
this.month=month;
this.day=day;
}
/*
* 改写toString方法
*/
public String toString() {
String tmp=name+"|"+this.salary+"|"+this.year+"-"+this.month+"-"+this.day;
return tmp;
}
}
另一个class
package LearnStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.time.LocalDate;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Employee[] staff=new Employee[3];//创建容量为三个的数组
staff[0]=new Employee("Carl",6500,2018,6,6);
staff[1]=new Employee("Hack",5500,2016,5,4);
staff[2]=new Employee("tony",3400,2017,6,3);
/*
* 将我们的数据写入文档中
*/
try(PrintWriter out=new PrintWriter("D:/Data.txt","UTF-8")){
for(int i=0;i<staff.length;i++)
out.println(staff[i]);
out.close();
}
/*
* 将输入的数据读出来
*/
try(BufferedReader in=new BufferedReader(new FileReader("D:/Data.txt")) ){
Employee[] employeeNew=readData(in);
in.close();
for(Employee e:employeeNew) {
System.out.println(e);
}
}
}
public static Employee[] readData(BufferedReader in) throws IOException {
int n=3;
//测得一共有多少个数据
Employee[] employee=new Employee[n];
n=0;
while(n<3) {
String line=in.readLine();
String[] data=line.split("\\|");//这里因为|是正字表达式中的符号,需要用到两个来进行转义
double slary=Double.parseDouble(data[1]);
String[] date=data[2].split("-");
int year=Integer.parseInt(date[0]);
int month=Integer.parseInt(date[1]);
int day=Integer.parseInt(date[2]);
employee[n++]=new Employee(data[0],slary,year,month,day);
}
return employee;
}
}
仔细想想其实还是挺好玩的,当然垃圾代码也是没谁了
读写二进制数据
读写二进制数据,就是将数据变成二进制的数据,从人可直接看懂,到只有机器看懂的数据,当然这也算是一种加密吧
DataInput接口,DataOutput接口接口定义了下面用于二进制写数组、字符、boolean值和字符串的方法:
writeChars()等等