操作文件就是IO
IO流-1.0(文件操作) 也就是读取硬盘数据的操作,介绍一下文件
文件
数据存放的地方
什么是IO流
把数据从硬盘读取到内存==>I
流
把数据从内存存到硬盘==>O
流
File File可以指向一个文件,也可以指向目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package com.manu3.file;import java.io.File;public class FileDemo { public static void main (String[] args) { File f1 = new File("/home/manu" ); File f2 = new File("/home/manu/Java/src/day1/Math.java" ); System.out.println(f1.isDirectory()); System.out.println(f1.isFile()); System.out.println(f2.isFile()); System.out.println(f2.exists()); System.out.println(f2.canRead()); System.out.println(f2.canWrite()); System.out.println(f2.canExecute()); } }
创建和删除
1 2 3 4 5 6 7 8 9 10 11 12 13 public class FileDemo { public static void main (String[] args) throws IOException { File f1 = new File("/home/manu/Java/Test.md" ); File f2 = new File("/home/manu/Java/Test" ); f1.createNewFile(); f2.mkdir(); f2.mkdirs(); f1.renameTo(new File("/home/manu/Java/Test2.md" )); f2.delete(); } }
获取一些信息
1 2 3 4 5 6 7 8 9 10 11 12 13 public class FileDemo { public static void main (String[] args) throws IOException { File f1 = new File("/home/manu/Java/Test2.md" ); File f2 = new File("Test" ); System.out.println(f1.getAbsolutePath()); System.out.println(f2.getPath()); System.out.println(f1.getName()); System.out.println(f1.length()); System.out.println(f1.lastModified()); System.out.println(f1.getParent()); } }
list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import java.io.File;import java.io.IOException;public class FileDemo { public static void main (String[] args) throws IOException { File dir = new File("/home/manu/Java_learn_workspace/Learn02" ); String[] s = dir.list(); for (String i : s) { System.out.println(i); } File[] s2 = dir.listFiles(); for (File i : s2) { System.out.println(i.getName()); } }
两个题目,觉得挺有意思,放上来
1.复制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.manu4.practice;import java.io.File;import java.io.IOException;import java.nio.file.Files;public class CopyFiles { public static void main (String[] args) throws IOException { File source = new File("/home/manu/Java/Test2.md" ); File target = new File("/home/manu/Java/Test2" ); Files.copy(source.toPath(), target.toPath()); } }
2.递归查找文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.manu4.practice;import java.io.File;public class RTD { public static void TraversalDiractory (File parentDir) { File[] temp = parentDir.listFiles(); for (File file : temp) { if (file.isFile()) { System.out.print(file.getName()+" " ); } } System.out.println(); for (File file : temp) { if (file.isDirectory()) { System.out.println(file.getPath()+" " ); TraversalDiractory(file.getAbsoluteFile()); } } } }
IO流-2.0(文件内容操作) 数据类型
数据流
字节流
抽象基类:InputStream OutputStream
字符流
字节流
默认没有缓冲区(代表频繁与硬盘交互,浪费性能)
操作一个字节
输入
InputStream–>FileInputStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public void testFileInputStream () { FileInputStream input = null ; try { input = new FileInputStream("Test/test1.txt" ); byte [] data = new byte [4 ]; while (true ) { int length = input.read(data); if (length==-1 ) break ; for (int i=0 ; i<length; i++) { System.out.print((char )data[i]); } String str = new String(data,0 ,length); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (input != null ) { input.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
输出
OutputSteam–>FileOutputStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Test public void testFileOutputStream () { FileOutputStream output = null ; try { output = new FileOutputStream("Test/test1.txt" ,true ); String str = new String("abcd" ); output.write(str.getBytes()); output.write(str.getBytes(), 1 , 3 ); }catch (IOException e) { e.printStackTrace(); } finally { try { if (output != null ) output.close(); }catch (Exception e) { e.printStackTrace(); } } }
文件文本的复制练习
我使用了字节数组完成
后面有对比单字节和字节数组效率的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.manu.iostream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class IOCopy { public static void copyFile (String source,String target) { FileInputStream input = null ; FileOutputStream output = null ; try { input = new FileInputStream(source); output = new FileOutputStream(target); byte [] data = new byte [1024 ]; int length=-1 ; while ((length=input.read(data))>-1 ) { String str = new String(data,0 ,length); output.write(str.getBytes()); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (input!=null ) input.close(); }catch (IOException e) { e.printStackTrace(); } try { if (output!=null ) output.close(); } catch (IOException e) { e.printStackTrace(); } } } }
1 2 3 4 5 6 7 8 9 10 public void testCopy () { long start = System.currentTimeMillis(); copyFileByArray("Test/test.zip" ,"Test/test2.zip" ); long end = System.currentTimeMillis(); System.out.println(end-start); start = System.currentTimeMillis(); copyFileByByte("Test/test.zip" ,"Test/test3.zip" ); end = System.currentTimeMillis(); System.out.println(end-start); }
结果(单位毫秒)
缓冲区 作用:节约性能,当缓冲区满时就会与硬盘交互
缓冲输出流(包装流) 缓冲区的数据只有在下面三种情况才会写入硬盘,之所以说是包装流是因为它依赖于File
满了
调用flush刷新缓冲区
调用close
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.manu5.buffer;import java.io.BufferedOutputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import org.junit.Test;public class TestBufferedOutputStream { @Test public void testBufferedOutputStream () { BufferedOutputStream bos = null ; try { bos = new BufferedOutputStream(new FileOutputStream("Test/test1.txt" ),1 ); bos.write(97 ); String str = new String("hello" ); bos.write(str.getBytes()); bos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bos!=null ) bos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
缓冲输入流 缓冲区的作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class BufferedIOStream { @Test public void testBufferedInputStream () { BufferedInputStream bis = null ; try { bis = new BufferedInputStream(new FileInputStream("Test/test1.txt" )); byte [] data = new byte [1024 ]; int length = bis.read(data); String str = new String(data,0 ,length); System.out.println(str); } catch (IOException e) { e.printStackTrace(); } }
字符流
操作一个Unicode码元(2字节)
默认是有缓冲区的,但不能设置大小
输出
Writer–>OutputStreamWriter(包装流)
构造OutputStreamWriter对象时,可以指定编码,默认系统编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.manu.iostream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import org.junit.Test;public class IO_WriterRead { @Test public void testOutputStreamWriter () { OutputStreamWriter writer = null ; try { FileOutputStream fileOutput = new FileOutputStream("Test/test1.txt" ); writer = new OutputStreamWriter(fileOutput); writer.write("你好" ); } catch (IOException e) { e.printStackTrace(); } finally { try { if (writer!=null ); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
输入
Reader–>InputStreamWriter(包装流)
构造InputStreamWriter对象时,可以指定编码,默认系统编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void testInputStreamReader () { InputStreamReader reader = null ; try { reader = new InputStreamReader(new FileInputStream("Test/test1.txt" ),"utf-8" ); char [] data = new char [1024 ]; int length = reader.read(data); System.out.println(new String(data,0 ,length)); } catch (IOException e) { e.printStackTrace(); } finally { try { if (reader!=null ) reader.close(); } catch (IOException e) { e.printStackTrace(); } } }
FileWriter
Writer–>OutputStreamWriter–>FileWriter
相对与OutputStreamWriter
,FileWriter
构造时时不需要new FileOutputStream
,因为它在调用父类构造方法时自动new FileOutputStream()
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Test public void testFileWriter () { FileWriter writer = null ; try { writer = new FileWriter("Test/test1.txt" ); writer.write("hello,我是manu!" ); } catch (IOException e) { e.printStackTrace(); } finally { try { if (writer!=null ) writer.close(); } catch (IOException e) { e.printStackTrace(); } } }
FileReader
Reader–>InputStreamReader–>FileReader
构造简单
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void testFileReader () { FileReader reader = null ; try { reader = new FileReader("Test/test1.txt" ); char [] data = new char [1024 ]; int length = reader.read(data); System.out.println(new String(data,0 ,length)); } catch (IOException e) { e.printStackTrace(); } finally { try { if (reader!=null ) reader.close(); } catch (IOException e) { e.printStackTrace(); } } }
如果要设定编码,则需要在构造时给出Charset型的数据即可
如
reader = new FileReader("Test/test1.txt",Charset.forName("GBK"));
BufferedWriter
Writer–>BufferedWriter
可以设置缓冲区大小
有一个readLine()
BufferedReader
Reader–>BufferedReader
可以设置缓冲区大小