黑马程序员——IO小结

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、IO

1IO概述

IO流用来处理设备之间的数据传输。

Java对数据的操作是通过流的方式。

Java用于操作流的对象都在IO包中。

2IO分类

流按操作数据分为两种:字节流与字符流。

其实计算机里的所有数据都是以字节的形式体现的,计算机可以直接识别字节。但是作为人类的程序员更擅长操作字符,所以后期产生了字符流 。

流按流向分为:输入流(input),输出流(output)

3相对路径与绝对路径:

绝对路径:从盘符开始指定的物理路径。是真正文件在硬盘上的位置。

相对路径:相对于某个指定位置的路径。 如c:/a/b/c.txt文件。相对于c:的路径为a/b/c.txt 。

代码中Windows中路径分隔可使用/或者\\

 

 

二、IO——File

1File概述:将文件路径或者文件夹路径封装成的类。实际代表该路径下的文件或者文件夹。方便对文件与文件夹的属性信息进行操作。

2File对象可以作为参数传递给流的构造函数。

A构造方法:

public File(String pathname)

public File(String parent, String child)

public File(File parent, String child)

B主要方法(创建、删除、判断、重命名)

public boolean createNewFile() throws IOException

public boolean mkdir()

public boolean mkdirs()

public boolean delete()

public boolean isFile()

public boolean isDirectory()

public boolean exists()

public boolean isHidden()

public boolean renameTo(File dest)重命名/剪切

C主要方法(获取、高级获取):

public String getAbsolutePath()

public String getPath()获取file内封装的内容

public String getParent()

public File getParentFile()

public String getName()

public long length()

public long lastModified()

 

public static File[] listRoots()

public String[] list()及加入过滤器的使用

public File[] listFiles()及加入过滤器的使用

D文件过滤器FilenameFilter:用于过滤文件

主要方法:

boolean accept(File dir, String name)

dir:该文件所在目录 name:该文件名return:是否将该文件加入返回的数组

案例:返回某文件夹下所有以java结尾的文件
package io;

import java.io.File;
import java.io.FilenameFilter;

public class FileTest {
	public static void main(String[] args) {
		File file = new File("e:\\javaweb");
//使用listFiles方法加文件过滤器
		File[] files = file.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				File thisFile = new File(dir, name);
				if (thisFile.isFile()) {
					if (name.endsWith(".java"))
						return true;
				}
				return false;
			}
		});
		for (File file2 : files) {
			String s = file2.toString();
			System.out.println(s);
		}
	}
}


 

三、IO——递归算法

1递归:在函数内调用函数本身。

2递归注意事项:

必须在函数内调用该函数本身。

递归算法所在函数内,必须有函数出口。

递归次数不能过多,否则会导致内存溢出。

例如:
1、使用递归完成一个数的阶乘
	public int getSum(int i) {
		if (i == 1)
			return 1;
		return getSum(i - 1) * i;
	}
2、使用递归计算斐波那契数列
	public int Fibonacci(int i) {
		if (i == 1 || i == 2)
			return 1;
		return Fibonacci(i - 1) + Fibonacci(i - 2);
	}

四、IO——字节流

字节流:操作对象为字节的IO

1、字节输出流:OutputStream

直接操作文件的子类为FileOutputStream

A、主要方法:

public abstract void write(int b) throws IOException

public void write(byte[] b) throws IOException

public void write(byte[] b, int off, int len) throws IOException

public void flush() throws IOException

public void close() throws IOException

写出时,windows的回车为:\r\n

B注意事项:

1文件名可以没有扩展名,文件夹可以有扩展名。文件与文件夹互不能同名。

2使用(File file)(String name)参数的构造方法,写出是覆盖操作。

3使用(File file,boolean append)(String name,boolean append)参数的构造方法,写出是追加操作。

4使用一次一个字节的方式,无法直接输出中文。可以使用一次一个字节数组的方式。

5如果写出目标的这个文件不存在,则在写出时,直接创建一个文件,再写出。

 

2字节输入流:InputStream

直接操作文件的子类为FileInputStream

A、主要方法:

public abstract int read() throws IOException

public int read(byte[] b) throws IOException

public int read(byte[] b, int off, int len) throws IOException

public void close() throws IOException

 

3高效字节流:将原有IO流进行包装,使其效率更高。

高效字节输出流:BufferedOutputStream

高效字节输入流:BufferedInputStream


 

案例:复制多级目录
package io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/*
 * 分析:
 *		A:封装目录为File对象
 *     		B:判断File对象是目录还是文件
 * 			如果是目录,在目的地创建同名目录。
 *			如果是文件,就复制。
 */
public class CopyDir {
	public static void main(String[] args) throws IOException {
		File source = new File("e:\\javacode\\java");
		File target = new File("e:\\javaweb");
		copyDir(source, target);
	}

	// 拷贝目录
	private static void copyDir(File source, File target) throws IOException {
		// 判断source
		if (source.isDirectory()) {// 是目录
			// 在target下创建同名目录
			File dir = new File(target, source.getName());
			dir.mkdirs();
			// 遍历source下所有的子文件,将每个子文件作为source,将新创建的目录作为target进行递归。
			File[] files = source.listFiles();
			for (File file : files) {
				copyDir(file, dir);
			}
		} else {// 是文件
			// 在target目录下创建同名文件,然后用流实现文件拷贝。
			File file = new File(target, source.getName());
			file.createNewFile();
			copyFile(source, file);
		}
	}

	// 拷贝文件
	private static void copyFile(File source, File file) throws IOException {
		// 创建流对象,使用高效字节流提高效率
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			// 基本读写操作
			bis = new BufferedInputStream(new FileInputStream(source));
			bos = new BufferedOutputStream(new FileOutputStream(file));			
			byte[] bys = new byte[1024];
			int len = 0;
			while ((len = is.read(bys)) != -1) {
				os.write(bys, 0, len);
			}
		} finally {
			if(bis!=null)
				try {
					bis.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			if(bos!=null)
				try {
					bos.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
		}	
	}
}


 

五、IO——字符流

操作对象为字节的IO

1字符输出流:Writer

直接操作文件的子类为FileWriter

A、主要方法:

public void write(int c) throws IOException

public void write(char[] cbuf) throws IOException

public abstract void write(char[] cbuf, int off, int len) throws IOException

public void write(String str) throws IOException

public void write(String str, int off, int len) throws IOException

2字符输入流:Reader

直接操作文件的子类为FileReader

A、主要方法:

public int read() throws IOException

public int read(char[] cbuf) throws IOException

public abstract int read(char[] cbuf, int off, int len) throws IOException

 

3高效字符流:将原有IO流进行包装,使其效率更高。

高效字节输出流:BufferedWriter

特殊方法:

public void newLine() throws IOException

高效字节输入流:BufferedReader

特殊方法:

public String readLine() throws IOException

案例:自定义类模拟BufferedReader的readLine()功能
package io;

import java.io.FileReader;
import java.io.IOException;
public class MyBufferedReader {
//FileReader作为成员变量使用,程序中使用字符串缓冲区拼写字符串
	private FileReader fr;
	MyBufferedReader(FileReader fr) {
		this.fr = fr;
	}
	public String myReadLine() throws IOException{
		StringBuilder sb = new StringBuilder();	
		int ch = 0;
		while((ch=fr.read())!=-1){
//换行:\r\n来判断是否为一行
			if(ch=='\r')
				continue;
			if(ch=='\n')
				return sb.toString();
			else
				sb.append((char)ch);
		}
		if(sb.length()!=0)
			return sb.toString();
		return null;
	}
	
	public void myClose() throws IOException {
		fr.close();
	}
	
	public static void main(String[] args) throws IOException {
		MyBufferedReader mbf = new MyBufferedReader(new FileReader("files\\buf.txt"));
		String line ;
		while((line=mbf.myReadLine())!=null) {
			System.out.println(line);
		}
		mbf.myClose();
	}
}

 

六、IO——转换流

1转换流OutputStreamWriter:字符流通向字节流的桥梁。

2转换流InputStreamReader:字节流通向字符流的桥梁。

3InputStreamReaderReader的子类,是FileReader的父类,是字符流的一种。

4OutputStreamWriterWriter的子类,是FileWriter的父类,是字符流的一种。

5转换流构造方法中,均有字节流与编码表两个参数。

6字符 字节 编码表

7、一般使用代码格式

InputStreamReader isr = new InputStreamReader(System.in);
InputStreamReader isr = new InputStreamReader(new FileInputStream(...));

OutputStreamWriter osw = new OutputStreamWriter(System.out);
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(...));
System.in:用于控制台录入,属于字节输入流
System.out:用于控制台输出,属于字节输出流

 

七、IO——编码表

1编码表:将字符与数字对应的码表。

2常见码表

ASCII:美国标准信息交换码。

ISO8859-1:拉丁码表。欧洲码表。

GB2312:中国的中文编码表。

GBK:中国的中文编码表升级,融合了更多的中文文字符号。

BIG-5码 :通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。

Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode

UTF-8:最多用三个字节来表示一个字符。

3编码表使用。

原则:编码与解码码表统一即可。

4字符串的使用

字符转成字节数组时,指定码表。

字节数组转成字符串时,指定码表。

5IO转换流使用

创建转换流对象时,使用编码。

与字符串共同使用时,保证编码统一。


 

八、其他IO

1数据输入输出流:数据输入输出流针对于基本数据类型。

DataInputStream:数据输入流

DataOutputStream:数据输出流

注意:在数据输入输出流的操作过程中,必须按照写入顺序读取,否则由于读取规则的不同,会造成乱码。

 

2内存操作流

ByteArrayInputStream:从数组中读取字节

ByteArrayOutputStream:将字节写入到数组中

CharArrayReader:从数组中读去字符

CharArrayWriter:将字符写到数组中

StringWriter:将字符写到字符串中

StringReader:从字符串中读取数据

注意:有些IO操作流流关闭无效,不会产生IO异常。如ByteArray操作流与String操作流

 

3打印流:专门用于数据打印的IO流。

A特点:

专注于输出,不关心数据输入,可以打印任意类型。

PrintStream :字节打印流

PrintWriter :字符打印流

B可以作为普通的输出流。

public void print(char c)

public PrintWriter printf(String format, Object... args) 

public void println()

printfprintln方法支持自动刷新

案例:通过打印流进行文本文件的复制。

	BufferedReader br = new BufferedReader(new FileReader("a.txt"));
	PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
	String line = null;
	while((line=br.readLine())!=null) {
		pw.println(line);
	}
	pw.close();
	br.close();

4随机访问流:对文件进行随机访问:RandomAccessFile

A特点

同时支持读与写。

需要指定模式。使用“rw”模式。

B特殊方法:

public long getFilePointer() throws IOException

注意writerUTF的指针字节个数。

public void seek(long pos) throws IOException

 

5对象序列化流:将对象作为数据进行操作。

序列化流:ObjectOutputStream

public final void writeObject(Object obj) throws IOException

反序列化流:ObjectInputStream

public final Object readObject() throws IOException, ClassNotFoundException

被序列化的对象必须可序列化,即实现序列化接口作为可序列化的标记。

 

Serializable:序列化接口

无方法,仅作为可序列化标记使用

写出与读入时,序列化ID必须相同

 

九、IO流相关类——Properties

该类是Hashtable的子类。用于存储属性键值对,通常作为配置文件来使用。

1特点

键值对均为字符串,可以直接操作IO

2特殊方法:

public String getProperty(String key) 及其重载

public Object setProperty(String key, String value)

public void list(PrintStream out)

public void store(OutputStream out, String comments) throws IOException

public void load(InputStream inStream) throws IOException


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值