1.File类
- java.io.File类:文件和文件目录路径的抽象表示形式
- File能新建、删除、重命名文件和目录,但File不能访问文件内容本身。如需要访问,需要输入\输出流
- File对象可以作为参数传递给流的构造器
File类的方法使用
public class FileTest {
//创建File类的实例
//File类中涉及到关于文件或目录的创建、删除、重命名、修改时间、文件大小的方法,并未涉及读写内容的操作
//File类的对象常会作为参数传递到流的构造器中
@Test
public void test1() {
File file1 = new File("hello.txt");//相对于当前Model路径
//路径分隔符 windows\\ unix/
File file2 = new File("C:" + File.separator + "Users" + File.separator + "IdeaProjects\\JavaBasis");//绝对路径
File file3 = new File("D:/work", "Java");
File file4 = new File(file3, "hi.txt");
//File的方法使用
File file = new File("D:/io/");
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getPath());
System.out.println(file1.getName());
System.out.println(file1.getParent());
System.out.println(file1.length());
System.out.println(file1.lastModified());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.exists());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isHidden());
String[] list = file.list();
for (String s : list) {
System.out.println(s);
}
File[] files = file.listFiles();
for (File f : files) {
System.out.println(f);
}
}
//创建硬盘中对应的文件或目录,删除
@Test
public void test2() throws IOException {
File file = new File("hi.txt");
if (!file.exists()) {
file.createNewFile();
System.out.println("创建成功");
} else {
file.delete();
System.out.println("删除成功");
}
File file1 = new File("D:/io/io2");
boolean mkdir = file1.mkdir();
if (mkdir) {
System.out.println("创建成功");
}
}
}
2. IO原理及分类
- Input/Output,用于处理设备间的数据传输,如读写文件,网络通讯
- Java中,对于数据的输入/输出以“流(stream)”的方式进行
- java.io包下提供了各种流类和接口,用以获取不同种类的数据,并以标准的方法输入或输出数据
- 按操作数据单位不同分为:字节流(8bit),字符流(16bit)
- 按数据流的流向不同:输入流,输出流
- 按流的角色不同:节点流,处理流
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
3. 节点流(文件流)
public class FileReaderWriterTest {
@Test
public void testFileReader() {
FileReader fr = null;
try {
File file = new File("hello.txt");
fr = new FileReader(file);
//read()返回读入的一个字符,如果达到文件末尾,返回-1
int len;
char[] cbuf = new char[5];
while ((len = fr.read(cbuf)) != -1) {
// for (int i = 0; i < len; i++) {
// System.out.println(cbuf[i]);
// }
String str = new String(cbuf, 0, len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//流的关闭
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void testFileWriter() {
FileWriter fileWriter = null;
try {
File file = new File("hello1.txt");
fileWriter = new FileWriter(file, true);
fileWriter.write("hello\n");
fileWriter.write("world");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileWriter != null) {
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void testFileCopy() {
FileReader reader = null;
FileWriter writer = null;
try {
File srcFile = new File("hello.txt");
File destFile = new File("hello1.txt");
reader = new FileReader(srcFile);
writer = new FileWriter(destFile);
char[] cbuf = new char[5];
int len;//记录每次读入到cbyf数组中字符的个数
while ((len = reader.read(cbuf)) != -1) {
//每次写出len个字符
writer.write(cbuf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class FileInputStreamTest {
@Test
public void testFileInputStream() {
FileInputStream inputStream = null;
try {
File file = new File("hello.txt");
inputStream = new FileInputStream(file);
byte[] buffer = new byte[5];
int len;//记录每次读取字节的个数
while ((len = inputStream.read(buffer)) != -1) {
String s = new String(buffer, 0, len);
System.out.print(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void testFileCopy() {
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
File srcFile = new File("wx.png");
File destFile = new File("ex.png");
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(destFile);
byte[] buffer = new byte[5];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//指定路径下文件的复制
public void copyFile(String srcPath, String destPath) {
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try {
File srcFile = new File(srcPath);
File destFile = new File(destPath);
inputStream = new FileInputStream(srcFile);
outputStream = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4. 缓冲流(处理流的一种)
/*处理流之一缓冲流的使用
* BufferedInputStream BufferedOutputStream
* BufferedReader BufferedWriter
* 内部提供了一个缓冲区,提高流的读取、写入的速度
* */
public class BufferedTest {
@Test
public void bufferedStreamTest() {
FileInputStream fis = null;
FileOutputStream fps = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File srcFile = new File("ex.png");
File destFile = new File("wx2.png");
fis = new FileInputStream(srcFile);
fps = new FileOutputStream(destFile);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fps);
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
//bos.flush();//刷新缓冲区
}
// String data;
// while((data=br.readLine())!=null){
// bw.write(data);
// bw.newLine():
// }
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
//fps.close();
//fis.close();
}
}
}
5. 转换流
- 提供了在字节流和字符流之间的转换
- InputStreamReader:InputStream->Reader
- OutputStreamWriter:Writer->OutputStream
- 字节流中的数据都是字符时,转成字符流操作更高效
- 很多时候实现编码和解码的功能
/*处理流之二:转换流的使用
* 提供字节流与字符流之间的转换
* */
public class InputStreamReaderTest {
@Test
public void test1() throws IOException {
FileInputStream fis = new FileInputStream("hello.txt");
FileOutputStream fos = new FileOutputStream("h2.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
char[] cbuf = new char[10];
int len;
while ((len = isr.read(cbuf)) != -1) {
osw.write(cbuf,0,len);
}
osw.close();
isr.close();
}
}
6. 标准输入、输出流
- System.in和System.out分别代表了系统标准的输入和输出设备
- System.in的类型是InputStream,System.out的类型是PrintStream
- 重定向:通过System类的setIn,setOut方法对默认设备进行改变
public class OtherStreamTest {
//标准输入输出流
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
while (true) {
System.out.println("输入");
String data = br.readLine();
if ("exit".equalsIgnoreCase(data)) {
System.out.println("程序结束 ");
break;
}
String s = data.toUpperCase();
System.out.println(s);
}
br.close();
}
}
7. 打印流
- 将基本数据类型的数据格式转化为字符串输出
- PrintStream和PrintWriter提供了一系列的print()和println()方法,用于多种数据类型的输出,有自动flush功能
8. 数据流
- 为了方便操作Java的基本数据类型和String的数据,可以使用数据流
- DataInputStream和DataOutputStream分别套在InputStream和OutputStream子类的流上
@Test
public void test1() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("gai");
dos.flush();//刷新操作,将内存中的写入文件
dos.writeInt(22);
dos.flush();
dos.writeBoolean(true);
dos.flush();
dos.close();
}
@Test
public void test2() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
System.out.println(dis.readUTF());
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
dis.close();
}
9. 对象流
- ObjectInputStream和ObjectOutputStream,用于存储和读取基本数据类型数据或对象的处理流,可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来
- 序列化:ObjectOutputStream保存基本类型数据或对象的机制
- 反序列化:ObjectInputStream读取基本类型数据或对象的机制
- 不能序列化static和transient修饰的成员变量
对象序列化机制允许把内存中的Java对象转换成二进制流,从而允许把这种二进制流持久地保存在磁盘中,或通过网络将这种二进制流传输到另一个网络节点
为了让某个类是可序列化地,该类必须实现两个接口之一:Serializable、Externalizable,其内部属性也必须是可序列化的
private static final long serialVersonUID;用来表明类的不同版本间的兼容性
//对象流的使用ObjectInputStream和ObjectOutputStream
public class ObjectStreamTest {
//序列化过程
@Test
public void test1() throws IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new Person("天才",10));
oos.flush();
oos.close();
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
}
10. 随机存取文件流
- RandomAccessFile类声明在java.io包下,直接继承于java.lang.Object类,这个类既可以读也可以写,程序可以直接跳到文件的任意地方来读写文件
public class RandomAccessFileTest {
@Test
public void test1() throws IOException {
RandomAccessFile raf1 = new RandomAccessFile(new File("ex.png"), "r");
RandomAccessFile raf2 = new RandomAccessFile(new File("ex1.png"), "rw");
byte[] buffer = new byte[1024];
int len;
while ((len = raf1.read(buffer)) != -1) {
raf2.write(buffer, 0, len);
}
raf1.close();
raf2.close();
}
//使用RandomAccessFile实现插入效果
@Test
public void test2() throws IOException {
//如果写到的文件存在,则对原有文件从头覆盖
RandomAccessFile raf1 = new RandomAccessFile("hello.txt", "rw");
raf1.seek(3);//文件为3的位置
StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while ((len = raf1.read(buffer)) != -1) {
builder.append(new String(buffer,0,len));
}
raf1.seek(3);
raf1.write("xyz".getBytes());
//将StringBuild写入
raf1.write(builder.toString().getBytes());
raf1.close();
}
}
11. NIO.2中Path、Paths、Files类的使用
- Java NIO(Non-Blocking IO)是Java1.4后开始引入一套新的IO API,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作
- Java API提供了两套NIO,一套是针对标准输入输出NIO,一套是网络编程NIO
- JDK7后,Java对NIO进行了扩展NIO.2,增强了对文件处理喝文件系统特性的支持
- Path可以看成是File类的升级版本,Files用于操作文件或目录的工具类