1、java.io.File类用于表示文件(目录),File类只用于表示文件(目录)的信息(名称、大小),不能用于文件内容的访问
package com.imooc.file;
import java.io.File;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args){
//创建一个目录对象(路径使用双反斜杠,因为是转义字符)
File file = new File("e:\\java\\imooc");
//使用file.separator分隔符,任何操作系统都认识
File file2 = new File("e:"+File.separator+"java"+File.separator+"imooc"+File.separator+"imooc2");
System.out.println(file2.exists());
if(!file2.exists()){
//file2.mkdir();//只能创建单级目录
file2.mkdirs();//创建多级目录
}
System.out.println(file2);
//判断是否是一个目录
System.out.println(file.isDirectory());
//是否是一个文件
System.out.println(file.isFile());
//创建文件
//File file3 = new File("e:\\java\\日记1.txt");
//另一种构建方法
File file3 = new File("e:\\java","日记1.txt");
if(!file3.exists()){
try {
file3.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
file3.delete();//删除目录
}
//常用的File对象的api
System.out.println(file3.toString());//文件的路径
System.out.println(file3);//file.toString()的内容文件的路径
System.out.println(file3.getAbsolutePath());//文件的路径
System.out.println(file3.getName());//文件的名字
System.out.println(file3.getParent());//父目录的名字
}
}
2、遍历目录list方法
package com.imooc.file;
import java.io.File;
import java.io.IOException;
import javax.lang.model.element.Element;
/**
* 列出File的一些常用操作比如过滤、遍历操作
* @author Administrator
*
*/
public class FileUtils {
public static void main(String[] args) throws IOException{
FileUtils.listDirectory(new File("e:\\java"));
}
/**
* 列出指定目录下(包括其子目录)的所有文件
*/
public static void listDirectory(File dir)throws IOException{
if(!dir.exists()){
throw new IllegalArgumentException("目录:"+dir+"不存在");
}
if(!dir.isDirectory()){
throw new IllegalArgumentException(dir+"不是目录 ");
}
/*String[] filenamesStrings = dir.list();//返回的是字符串数组,直接子的名称 不包含子目录下的内容
for (String string : filenamesStrings) {
System.out.println(dir+"\\"+string);
}*/
//如果要遍历子目录下的内容 就需要构造成File对象做递归操作,File提供了直接返回File对象的api
File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象
if(files!=null&&files.length>0){
for (File file : files) {
if(file.isDirectory()){
//递归
listDirectory(file);
}else {
System.out.println(file);
}
}
}
}
}
3、RandomAccessFile
(1)java提供的对文件内容的访问,既可以读文件,也可以写文件且支(2)持随机访问文件,即可以访问文件的任意位置
(3)java文件模型:在硬盘中是byte byte byte 存储的,是数据的集合
(4) 打开文件:有两种模式“rw”(读写)、“r”(只读)
RandomAccessFile raf = new RandomAccessFile(file,”rw”)
文件指针,打开文件时指针在开头pointer =0;
(5)写方法
int b = raf.write(int);—–只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
(6)读方法
int b = raf.read()—读一个字节
(7)文件读写完成以后一定要关闭(oracle官方说明若不关会有意想不到的错误d)
4、IO流(输入流、输出流)
字节流、字符流
1、字节流
1)InputStream:抽象了应用程序读取数据的方式
OutputStream:抽象了应用程序写出数据的方式
2)EOF=End或读到-1,就是结尾
3)输入流的基本方法
int b = in.read();//读取一个字节无符号填充到int的第八位。-1是EOF
in.read(byte[] buf)//读取数据填充到字节数组buf
in.read(byte[] buf,int start,int size)//读取数据到字节数组buf,从start开始长度为size
4)输出流的基本方法
out.write(int b)//写一个byte到流,b的低八位,int是32为
out.write(byte[] buf)将buf 字节数组都写入到流
out.write(byte[] buf,int start,int size
5)子类FileInputStream—-具体实现了在文件上读取数据
package com.imooc.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class IOUtil {
public static void main(String[] args) {
/*try {
IOUtil.printHex("e:\\java\\HelloWorld.class");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
try {
IOUtil.printHexByByte("e:\\java\\HelloWorld.class");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*read()方法读取单个字节
*读取指定文件的内容,按照16进制 输出到控制台
*并且每输出10个byte换行
* @throws FileNotFoundException
*/
public static void printHex(String fileName) throws IOException{
//把文件作为字节流进行读操作
FileInputStream in = new FileInputStream(fileName);
int b;
int i = 1;
while ((b=in.read())!=-1) {
if(b<=0xf){
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
if(i++%10==0){
System.out.println();
}
}
in.close();
}
/**
* 带参数的read()方法可以一次读取多个字节
* 从in中读取字节到数组buf中
* 从第零个开始最多读buf.length个
* 返回的是读到的字节的个数
*/
public static void printHexByByte(String fileName) throws IOException{
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[20*1024];//20k
/*int bytes = in.read(buf,0,buf.length);
int j = 1;
for(int i=0;i<bytes;i++){
if(buf[i]<=0xf){
System.out.println("0");
}
System.out.print(Integer.toHexString(buf[i])+" ");
if(j++%10==0){
System.out.println();
}
}*/
/**
* 当buf不够大时,用while循环控制当buf读满时重新再读
* byte类型为8为,int类型为32位为了避免数据转换类型错误,
* 通过0xff将高24为清零 ,当buf足够大时则不用清零,因为数组buf默认初始化为0
*/
int bytes = 0;
int j = 1;
while((bytes = in.read(buf,0,buf.length))!=-1){
for(int i=0;i<bytes;i++){
System.out.print(Integer.toHexString(buf[i]&0xff)+" ");
if(j++%10==0){
System.out.println();
}
}
}
}
}
6)子类FileOutputStream—-具体实现了在文件上读取数据
package com.imooc.file;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputDemo {
public static void main(String[] args) throws IOException {
//当文件不存在时,直接创建文件,如果存在,删除后创建
FileOutputStream out = new FileOutputStream("demo/out.dat");
//当文件存在时,会往文件后面追加内容
//FileOutputStream out = new FileOutputStream("demo/out.dat",true);
out.write('A');//写入低八位
out.write('B');//write只能写如八位,所以要写四次
int a = 10;
out.write(a>>>24);
out.write(a>>>16);
out.write(a>>>8);
out.write(a);
byte[]gbk = "中国".getBytes("gbk");
out.write(gbk);
out.close();
IOUtil.printHex("demo/out.dat");//双斜杠单斜杠都可以
}
7)实现文件的拷贝功能
public static void copyFile(File srcFile, File desFile) throws IOException {
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件:" + srcFile + "不存在!");
}
if (!srcFile.isFile()) {
throw new IllegalArgumentException(srcFile + "不是文件!");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(desFile);
byte[] buf = new byte[8 * 1024];
int b;
while ((b = in.read(buf, 0, buf.length)) != -1) {
out.write(buf, 0, b);
out.flush();// 最好加上
}
in.close();
out.close();
}
8)DataOutputStream和DataInputStream
对流功能的扩展,可以更加方便的读取int 、long字符等类型数据
DataOutputStream中增加方法
writeInt()和writeDouble()和writeUTF()等方法
1、package com.imooc.file;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class DosDemo {
public static void main(String[] args) throws IOException {
String file="e:\\java\\3.txt";
//新建dataoutputstream流将数据写入基础fileoutputstream流
DataOutputStream dos =
new DataOutputStream(new FileOutputStream(file));
dos.writeInt(10);
dos.writeInt(-10);
dos.writeLong(10l);
dos.writeDouble(10.5);
//采用utf-8编码写出
dos.writeUTF("中国");
//采用utf-16be
dos.writeChars("中国");
dos.close();
IOUtil.printHex(file);
}
}
2、
package com.imooc.file;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class DisDemo {
public static void main(String[] args)throws IOException {
String file = "e:\\java\\3.txt";
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int i = dis.readInt();
System.out.println(i);
i = dis.readInt();
System.out.println(i);
long l = dis.readLong();
System.out.println(l);
double d = dis.readDouble();
System.out.println(d);
String s = dis.readUTF();
System.out.println(s);
char c = dis.readChar();
System.out.println(c);
char c2 = dis.readChar();
System.out.println(c2);
dis.close();
}
}
8)字节缓冲流
BufferedInputStream和BufferedOutputStream:读写文件时会加缓冲区提高性能
加入从应用程序中把输入放入文件,相当于将一缸水放入另一缸中
FileOuputStream---write()一滴一滴的转移
DataOutputStream----writeXxx():一瓢一瓢的转移
BufferedOutputStream----write方法:一瓢一瓢的放入桶中在放入缸中
9)copy文件的三种方法
/**
* 文件的copy操作,批量拷贝(最快的)
*/
public static void copyFile(File srcFile, File desFile) throws IOException {
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件:" + srcFile + "不存在!");
}
if (!srcFile.isFile()) {
throw new IllegalArgumentException(srcFile + "不是文件!");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(desFile);
byte[] buf = new byte[8 * 1024];
int b;
while ((b = in.read(buf, 0, buf.length)) != -1) {
out.write(buf, 0, b);
out.flush();// 最好加上
}
in.close();
out.close();
}
/**
* 利用带缓冲的流进行文件的copy操作,一个字节一个字节的读取(比不带缓冲的要快)
*/
public static void copyFileByBuffer(File srcFile,File desFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在!");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是一个文件");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desFile));
int c;
while((c=bis.read())!=-1){
bos.write(c);
bos.flush();//必须加上刷新缓冲区
}
bis.close();
bos.close();
}
/**
* 不带缓冲的一个字节一个字节的读
*/
public static void copyFileByByte(File srcFile,File desFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在!");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是一个文件");
}
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(desFile);
int c;
while((c=fis.read())!=-1){
fos.write(c);
fos.flush();//可以不加,最好加上
}
fis.close();
fos.close();
}
***5、字符流***
1)编码问题
一个项目有自己的编码类型,当将一个gbk编码的txt文件的文字复制到utf-8的文件中时文字变为utf-8编码,无乱码,当直接将一个gbk编码的文件复制到一个utf-8的项目下是会出现乱码
2)认识文本和文本文件
java的**文本**是16位无符号整数,是字符的unicode编码(双字节编码)
**文件**是byte byte byte ...的数据序列
**文本文件**是文本(char)序列按照某种编码方案(utf-8、utf-16be、gbk)序列化为byte 的存储的结果
3)字符流(Reader writer)
字符的处理,一次处理一个字符
字符的底层仍然是基本的字节序列
字符流的的基本实现:
InputStreamReader:完成byte流解析为char流,按照编码解析
OutputStreamWriter:提供char流到byte流,按照编package com.imooc.file;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class IsrAndOswDemo {
public static void main(String[] args)throws IOException {
FileInputStream in = new FileInputStream("e:\\java\\wenzi.txt");
InputStreamReader isr = new InputStreamReader(in);//默认项目的编码,当文件编码和项目编码不一致时,
//为实际项目编码
FileOutputStream out = new FileOutputStream("e:\\java\\wenzi2.txt");
OutputStreamWriter osw = new OutputStreamWriter(out);
/**
* 单个字符读取
*/
int c;
while((c=isr.read())!=-1){
System.out.print(c);
}
/**
* 批量读取,放入buffer数组中,从0开始,
* c是返回的读到的字符的个数
*/
char[] buffer = new char[8*1024];
int c;
while((c=isr.read(buffer, 0, buffer.length))!=-1){
String s = new String(buffer,0,c);
System.out.println(s);
//写入文件wenzi2.txt
osw.write(buffer,0,c);
osw.flush();
}
isr.close();
osw.close();
}
}
4)字符流操作的单位是字符,需要考虑编码问题,字节流操作的单位是字节,不用考虑编码问题
5)FileReader和FileWriter
/**
* 使用FileReader和FileWriter类可以直接操作文件(文件对象或文件路径)
*/
FileReader fr = new FileReader("e:\\java\\wenzi.txt");//当此处出 //现编码问题是就要使用InputStreamReader类了
FileWriter fw = new FileWriter("e:\\java\\wenzi3.txt");//当加上//true参数时,不会把已经存在的文件删除,而是在文件后面追加内容
char[] buffer = new char[8*1024];
int c;
while((c=fr.read(buffer, 0, buffer.length))!=-1){
fw.write(buffer,0,c);
fw.flush();
}
fr.close();
fw.close();
6)字符流的过滤器
BufferedReader------->readLine一次读一行
BufferedWriter\printWriter-------->一次写一行
package com.imooc.file;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class BrAndBwDemo {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader
(new InputStreamReader(new FileInputStream("e:\\java\\wenzi.txt")));
// BufferedWriter bw = new BufferedWriter
// (new OutputStreamWriter(new FileOutputStream(“e:\java\wenzi2.txt”)));
PrintWriter pw = new PrintWriter("e:\\java\\wenzi3.txt");
//PrintWriter pw = new PrintWriter(outputStream,boolean autoFlush);自动刷新
String line;
while((line = br.readLine())!=null){
System.out.print(line);//一次读一行但是并不能识别换行,需单独添加换行语句,
//这里是通过println换行的
// bw.write(line);//写入到文件wenzi2.txt
// bw.newLine();//换行
// bw.flush();//必须刷新缓冲区
pw.println(line);
pw.flush();
}
br.close();
//bw.close();
pw.close();
}
}
***6、序列化基本操作***
1)对象的序列化和反序列化:对象的序列化是将对象转换成byte序列,反之叫对象的反序列化
2)序列化流(ObjectOutputStream),是过滤流-----方法:writeObject
反序列流(ObjectInputStream),-------方法readObject
3)序列化接口(Serializable)
对象必须实现序列化接口 ,才能进行序列化,否则将出现异常,这个接口没有任何方法,只是一个标准
4)路径的斜杠问题:正斜杠通用字符串中可用单斜杠,反斜杠在字符串中则要双写
package com.imooc.file;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ObjectSerialDemo {
public static void main(String[] args)throws Exception{
String file = "demo/obj.dat";
//1、对象的序列化注意student类要实现serializable接口
/*ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream(file));
Student stu = new Student("10001","张三",20);
oos.writeObject(stu);
oos.flush();
oos.close();*/
//反序列化
ObjectInputStream ois = new
ObjectInputStream(new FileInputStream(file));
Student stu = (Student)ois.readObject();
System.out.print(stu);
ois.close();
}
}
“`
5)当给student类的某个属性加上transient关键字时该属性不会进行jvm默认的序列化,也可以自己完成这个元素的序列化
需要给student类加上一下两个方法,以便自己完成某些元素的序列化
//序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{}
//反序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException,ClassNotFoundException{}
分析ArrayList源码中序列化和反序列化的问题
5)序列化中子类和父类构造函数的调用问题
当对子类进行序列化时,如果其父类没有实现序列化接口,那么其父类的构造函数会被调用,否则不被调用