文件-使用File类操作文件:
什么是文件? 文件可认为是相关记录或放在一起的数据的集合。
文件一般存储在哪里? 储存在存储设备里。
Java程序如何访问文件? Java API:java.io.File 类
File类访问文件属性:
注意:
- 创建File文件要先new然后构造路径名称(类型是String)
- 当使用Java.io.File类创建路径的时候文件名时不能用\要用\\或者/因为在JAva中\有转义的作用所以不能使用
- Java中的file并不仅仅指文件也可以指目录
方法名称 | 说明 |
boolean exists( ) | 判断文件或目录是否存在 |
boolean isFile( ) | 判断是否是文件 |
boolean isDirectory( ) | 判断是否是目录 |
String getPath( ) | 返回此对象表示的文件的相对路径名 |
String getAbsolutePath( ) | 返回此对象表示的文件的绝对路径名 |
String getName( ) | 返回此对象表示的文件或目录的名称 |
boolean delete( ) | 删除此对象指定的文件或目录 |
boolean createNewFile( ) | 创建名称的空文件,不创建文件夹 |
long length() | 返回文件的长度(单位为字节) |
注:
绝对路径:从计算机盘符(根目录)出发,到最后的文件
相对路径:从当前路径出发,到最后的文件
length():如果文件不存在,则返回 0L(L代表是long这个类型)
流:
通过流来读写文件:
流是有序的数据序列,是以先进先出方式发送信息的通道。
读数据是InputStream
写数据是OutputStream
Java流的分类:(输入是读,输出是写)
【输入输出流是相对于计算机内存来说的】
【字节流是8位通用字节流,字符流是16位Unicode字符流】
文本文件的读写:
- 用FileInputStream和FileOutputStream读写文本文件
- 用BufferedReader和BufferedWriter读写文本文件
二进制文件的读写:
使用DataInputStream和DataOutputStream读写二进制文件
InputStream(字节输入流,是一个抽象类)类常用方法:
int read( )
【一个字节一个字节的读出来,返回的是该字节的整数表示形式】
int read(byte[] b)
【从输出流读取若干字节,把这些字节保存到数组b中,返回的是读取到的字节数,如果到了输入流的末尾,返回-1】
int read(byte[] b,int off,int len)
【从输出流读取若干字节,把这些字节保存到数组b中,off指的是字节数组中开始保存数据的起始下标,len指返回的是读取到的字节数,返回的是读取到的字节数,如果到了输入流的末尾返回-1】
void close( )
【读流读完了应该关了】
int available()
【可以从输入流中读取的字节数目】
子类FileInputStream常用的构造方法:
FileInputStream(File file)
【可以传一个文件】
FileInputStream(String name)
【也可以写一个路径】
使用FileInputStream 读文本文件:
方法一(一个一个取出来):
FileInputStream fis = new FileInputStream("d:/java160.txt");
int ch;
while((ch=fis.read()) != -1){
System.out.print((char)ch);
}
方法二(存在数组里然后取出来):
byte[] bytes = new byte[1024];
int ch;
//ch表示读了多少字节,如果文件内容为空,则为-1
//一次读1024
while((ch=fis.read(bytes))!=-1){
for(int i = 0;i<ch;i++)
System.out.println((char)bytes[i]);
}
OutputStream类常用方法:
void write(int c)
void write(byte[] buf)
void write(byte[] b,int off,int len)
void close( )
void flush( ):【强制将缓冲区清空,有一些流自带很大的空间,先把字符都放在这个空间里,等满了就把缓冲区都放出去,所以flush就是强制把这些都冲出去( )】
子类FileOutputStream常用的构造方法:
FileOutputStream (File file)
FileOutputStream(String name)
FileOutputStream(String name,boolean append)
【boolean append可以指定覆盖或追加文件内容,如果boolean为true那就会是追加而不是覆盖】
写入方法:
fos = new FileOutputStream("d:/test/hello.txt");
String str = "好好学习";
//将字符打散成为一个字节数组
byte[] words = str.getBytes();
fos.write(words, 0,words.length);
System.out.println("文件已被更新");
常见错误【1. 少写了一个字节过来 2. 多写了很多空格过来】:
// 1、创建输入流对象,负责读取D:\我的青春谁做主.txt文件
FileInputStream fis = new FileInputStream("D:\\我的青春谁做主.txt");
//2、创建输出流对象,负责将文件内容写入到C:\myFile\my Prime.txt中
FileOutputStream fos = new FileOutputStream("C:\\myFile\\myPrime.txt",true);
// 3、创建中转站数组,存放每次读取的内容
byte words [] = new char[1024];
// 4、通过循环实现文件读写
while((fis.read())!=-1){
fis.read(words); //读取文件
fos.write(words, 0, words.length); } //写入文件
- 少写了一个字节过来是因为while((fis.read())!=-1)已经读了一次,然后又读到words里
- 多写了很多空格过来是因为fos.write(words, 0, words.length)中用的是words.length,其中words共有1024个位置,除了读到的之外还有很多空格所以也会输出
正确写法应该是:
int len = -1;
len =fis.read(words)) !=-1){
len); }
直接在while中把所有的都read出来,然后在写的时候要从零一直到设置的len【len是读到的所有字符的长度】
字符编码格式:按照一定的标准把字符编码能给中文编码的就是GBK、GB2312和ANSI
我们一般做的项目编码是UTF-8(国际通用的编码格式)
中文乱码:原因(文件编码格式和程序环境的编码格式不一样)
解决方法:
- 把windows的preferences的general中UTF-8改成GBK
- 把文件用UTF-8另存
- 字符流去读的时候,可以指定字符流的编码格式
System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
Reader类常用方法
【作用和用法都和InputStream一样,正常使用就可以】:
int read( )
int read(char[ ] c)
read(char[ ] c,int off,int len)
void close( )
为了解决中文乱码使用子类InputStreamReader
子类InputStreamReader常用的构造方法:
InputStreamReader(InputStream in)
InputStreamReader(InputStream in,String charsetName)
【支持输入的字符流,并且可以规定输入的字符编码格式】
孙子类FileReader类是InputStreamReader的子类【作用和用法都和FileInputStream一样,正常使用就可以】:
new FileReader(File file)
new FileReader(String name)
该类只能按照系统默认的字符编码来读取数据,用户不能指定其他的字符编码类型
System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
有中文乱码的缺陷所以一般使用InputStreamReader并且和FileInputStream fis = new FileInputStream("……"); 配合着来用
BufferedReader类:
如何提高字符流读取文本文件的效率?
使用FileReader类与BufferedReader类
BufferedReader类是Reader类的子类
BufferedReader类带有缓冲区
按行读取内容的readLine()方法(一行一行的读)【BufferedReader类特有的方法】
Reader类常用方法:
int read( )
int read(char[ ] c)
read(char[ ] c,int off,int len)
void close( )
子类BufferedReader常用的构造方法:
BufferedReader(Reader in)
子类BufferedReader特有的方法:
readLine()
注:
有时带缓冲区的流读不出东西来有可能是因为流没关,要用XXX.close关闭才能继续使用;当使用缓冲区的输出流时流一定要关闭
Writer类:
Writer类常用方法:
write(String str)
write(String str,int off,int len)
void close()
void flush()
子类OutputStreamWriter(可以指定字符编码格式)常用的构造方法:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
孙子类FileWriter:以下两种构造都可以重载,指定一个boolean类型的参数,用来指定追加还是覆盖文件内容
new FileWriter (File file)
new FileWriter (String path)
一定要记住使用.flush()和.close(),这样才能把存在缓冲区中的数据冲出来。
BufferedWriter类:
如何提高字符流写文本文件的效率?
使用FileWriter类与BufferedWriter类
【BufferedWriter类是Writer类的子类】
【BufferedWriter类带有缓冲区的输出流】
BufferedWriter常用的构造方法:
BufferedWriter(Writer out)
.newLine():换行(写一个新航)
读写二进制文件:
DataInputStream类:
是FileInputStream的子类
与FileInputStream类结合使用读取二进制文件
DataOutputStream类:
是FileOutputStream的子类
与FileOutputStream类结合使用写二进制文件
总结:
序列化、反序列化:
序列化和反序列化的过程:
序列化是将对象的状态写入到特定的流中的过程。
反序列化则是从特定的流中获取数据重新构建对象的过程。
对象输入流(反序列化):
ObjectInputStream
反序列化的输入方法:.readObject()【Object类型的,需要类型转换】
对象输出流(序列化):
ObjectOutputStream
序列化的输出方法:.writeObject(Object)
常见异常:
NotSerializableException:类没有实现Serializable接口,不可被序列化;要使用:implements Serializable来实现接口。
如果一个类想被序列化和他所有有关系的类都必须能被系列化(比如它的父类,子类…)
transient(关键字):屏蔽某些敏感字段的序列化
例如:private transient String password