一、IO
1、IO的概念2、流的概念 二、四大IO抽象类
1、java流的分类2、编码 三、IO类
1、File类2、字节输入输出流
2.1 字节流文件拷贝的方式2.2 字节缓存流实现文件的拷贝 3、文本字符输入输出流
3.1 字符流实现文件的拷贝3.2 字符缓存流实现文件的拷贝 4、转换流5、字节数组输入输出流6、对象流
一、IO 1、IO的概念在程序设计过程中,输入输出(Input/Output)尤为重要。程序在运行过程中需要获取外部数据进行 *** 作。其中外部数据可能保存在文件、数据库、网络、其他程序中等等。所以我们需要运用IO来 *** 作外部数据。
输入(Input):程序从外部系统获取数据的过程
输出(Output):程序输出数据到外部数据的过程
数据源(Data Source):提供数据的一端
流是一个抽象的概念,它就是一连串的数据。
输入流:通过流将数据源中的数据输送到程序中去
输出流:通过流将程序中的数据输送到数据源中
1、按数据流的方向:
输入流:数据流从数据源到程序
输出流 :数据流从程序到目的地
2、按处理数据单元:
字节流:以字节为单位获取数据
字符流:以字符为度单位获取数据
3、按处理对象不同:
节点流:可以直接从数据源或目的地址读写数据
处理流:不直接连接到数据源或目的地,通过对其他流的处理提高程序性能,也叫包装流
编码就是把字符转换为字节,而解码是把字节重新组合成字符。
如果编码和解码过程使用不同的编码方式那么就出现了乱码。
GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节;
UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节;
UTF-16be 编码中,中文字符和英文字符都占 2 个字节。
public class File extends Object implements Serializable, Comparable
File类的常用方法:
boolean delete() 删除由此抽象路径名表示的文件或目录。
boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
String[] list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
File[] listFiles() 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
boolean isFile() 测试此抽象路径名表示的文件是否为普通文件。
boolean isDirectory() 测试此抽象路径名表示的文件是否为目录。
测试:
public class FileDemo { public static void main(String[] args) throws IOException { File file = new File("C:Test.txt"); // 判断文件是否存在 if (!file.exists()) { // 创建文件 file.createNewFile(); } // 刪除文件 file.delete(); } }2、字节输入输出流
FileInputStream和FileOutputStream
2.1 字节流文件拷贝的方式// 方式一 public static void main(String[] args) throws IOException { String srcPath = "c:/test1.txt"; String DestPath = "d:/test1.txt"; int fileLen = 0; FileInputStream fileInputStream = new FileInputStream(srcPath); FileOutputStream fileOutputStream = new FileOutputStream(DestPath); byte[] buf = new byte[1024]; // fileInputStream.read()读取一个字节的数据 范围为0-255 // fileInputStream.read(buf)读取最多buf.length个字节的数据 while((fileLen = fileInputStream.read(buf)) != -1){ // 将filelen字节从0偏移量写入此文件输出流 fileOutputStream.write(buf,0,fileLen); } fileInputStream.close(); fileOutputStream.close(); }
// 方式2 public static void main(String[] args) throws IOException { String srcPath = "c:/test1.txt"; String DestPath = "d:/test1.txt"; int fileLen = 0; FileInputStream fileInputStream = new FileInputStream(srcPath); FileOutputStream fileOutputStream = new FileOutputStream(DestPath); // fileInputStream.available() 从此输入流中可以读取(或跳过)的剩余字节数的估计值 byte[] buf = new byte[fileInputStream.available()]; fileInputStream.read(buf); fileOutputStream.write(buf); fileInputStream.close(); fileOutputStream.close(); }
比较上述两个代码,我们发现方式2读写的速度更快,但是在实际应用中,如果我们要 *** 作的文件比较大时,建议选择方式1,因为方式2虽然速度快,但是空间消耗非常大。
提高文件 *** 作效率
前面我们可以通过byte[]数组达到数据缓冲的作用,Java有一种缓冲流,缓冲流本身不具有IO流的读写功能,它在别的流的基础上加上缓冲功能提高效率。
BufferedInputStream和BuffererdOutputStream
2.2 字节缓存流实现文件的拷贝public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { fis = new FileInputStream("c:/Test.txt"); bis = new BufferedInputStream(fis); fos = new FileOutputStream("c:/Test1.txt"); bos = new BufferedOutputStream(fos); // 缓冲流中byte数组长度默认为8192 // private static int DEFAULT_BUFFER_SIZE = 8192; int temp = 0; while((temp = bis.read()) != -1) { bos.write(temp); } bos.flush(); }catch (Exception e) { e.printStackTrace(); }finally { try { if(bos != null) { bos.close(); } if(fos != null) { fos.close(); } if(bis != null) { bis.close(); } if(fis != null) { fis.close(); } } catch (Exception e) { e.printStackTrace(); } } }3、文本字符输入输出流
FileReader和FileWriter
public static void FileReaderTest(String[] args) throws IOException { String filePath = "c:/test.txt"; FileReader fileReade = new FileReader(filePath);; int fileDate = 0; while((fileDate = fileReade.read()) != -1) { System.out.print((char) fileDate); } fileReade.close(); }
public static void FileWriterTest(String[] args) throws IOException { String filePath = "c:/note.txt"; FileWriter fileWriter = new FileWriter(filePath); // 写入一个字符 fileWriter.write("h"); // 写入一个字符数组 char[] buf = {'1','2','3','4'}; fileWriter.write(buf); // 写入字符串 String str = "小姜~超幸运,爱学习"; fileWriter.write(str); // 截取字符串内容并写入 fileWriter.write(str,0,6); fileWriter.close(); }
FileWriter提供的构造方法有FileWriter(File file, boolean append) ,这个构造方法有两个参数,第一个表示文件的路径,第二个表示是否可以追加,如果为true,则表示可以追加,反之为覆盖。
3.1 字符流实现文件的拷贝public static void main(String[] args) throws IOException { String filePath1 = "c:/test1.txt"; String filePath2 = "c:/test2.txt"; FileReader fr = new FileReader(filePath1); FileWriter fw = new FileWriter(filePath2); int fileDate = 0; char[] buf = new char[1024]; while((fileDate = fr.read()) != -1) { fw.write(buf,0,fileDate); } fw.close(); fr.close(); }
提高文件 *** 作效率
在字符流中同样有字符缓冲流对字符流增加缓存机制,大大提高了读写文件的效率。
BufferedReader和BufferedWriter
public static void BufferedReaderTest(String[] args) throws IOException { String filePath = "C:/test.txt"; BufferedReader br = new BufferedReader(new FileReader(filePath)); String str = ""; // br.readLine() 读取的是一行的内容 返回值为null结束 while((str = br.readLine()) != null) { System.out.println(str); } br.close(); }
public static void BufferedWriterTest(String[] args) throws IOException { String filePath = "c:/test.txt"; BufferedWriter bw = new BufferedWriter(new FileWriter(filePath)); bw.write("hello,小姜"); // 回车换行 bw.newline(); bw.write("hello,小姜n"); bw.close(); }3.2 字符缓存流实现文件的拷贝
public static void main(String[] args) throws IOException { String filePath1 = "c:/test1.txt"; String filePath2 = "c:/test2.txt"; BufferedReader br = new BufferedReader(new FileReader(filePath1)); BufferedWriter bw = new BufferedWriter(new FileWriter(filePath2)); String temp = ""; while((temp = br.readLine()) != null) { bw.write(temp); bw.newline(); } bw.flush(); bw.close(); br.close(); }4、转换流
InputStreamReader和OutputStreamWriter
将字节流转化成字符流
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 使用转换流输出 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 使用字符输出流输出 PrintWriter pw = new PrintWriter("d:/test.txt"); // 终端读取键盘输入文本内容 String input = br.readLine(); // 终端打印文本内容 bw.write(input); // 写入到文件中 pw.println(input); bw.close(); pw.close(); br.close(); }5、字节数组输入输出流
ByteArrayInputStream和ByteArrayOutputStream
public static void ByteArrayInputStreamTest(String[] args) { byte[] arr = "ancdefg".getBytes(); ByteArrayInputStream bis = new ByteArrayInputStream(arr); StringBuilder sb = new StringBuilder(); int temp = 0; while((temp = bis.read()) != -1) { sb.append((char)temp); } System.out.println(sb); }
public static void ByteArrayOutputStreamTest(String[] args) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); StringBuilder sb = new StringBuilder(); bos.write('a'); bos.write('b'); bos.write('c'); byte[] arr = bos.toByteArray(); for (int i = 0; i < arr.length; i++) { sb.append((char)arr[i]); } System.out.println(sb); }6、对象流
序列化
序列化就是将一个对象转换成字节序列,方便存储和传输。
序列化:ObjectOutputStream.writeObject()
反序列化:ObjectInputStream.readObject()
序列化的类需要实现 Serializable 接口,它是一个空接口,但是如果不去实现它的话而进行序列化,会抛出异常。
public class SerializationTest { public static void main(String[] args) throws IOException, ClassNotFoundException { String filePath = "d:/test.txt"; ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(filePath)); ObjectInputStream oi = new ObjectInputStream(new FileInputStream(filePath)); oo.writeObject(new JiaQi("小姜", 21)); JiaQi j = (JiaQi) oi.readObject(); System.out.println(j.toString()); oo.close(); oi.close(); } } class JiaQi implements Serializable { private String name; private int age; public JiaQi(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "JiaQi{" + "name='" + name + ''' + ", age=" + age + '}'; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)