------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、IO
1、IO概述
IO流用来处理设备之间的数据传输。
Java对数据的操作是通过流的方式。
Java用于操作流的对象都在IO包中。
2、IO分类
流按操作数据分为两种:字节流与字符流。
其实计算机里的所有数据都是以字节的形式体现的,计算机可以直接识别字节。但是作为人类的程序员更擅长操作字符,所以后期产生了字符流 。
流按流向分为:输入流(input),输出流(output)。
3、相对路径与绝对路径:
绝对路径:从盘符开始指定的物理路径。是真正文件在硬盘上的位置。
相对路径:相对于某个指定位置的路径。 如c:/a/b/c.txt文件。相对于c:的路径为a/b/c.txt 。
代码中Windows中路径分隔可使用/或者\\。
二、IO——File类
1、File概述:将文件路径或者文件夹路径封装成的类。实际代表该路径下的文件或者文件夹。方便对文件与文件夹的属性信息进行操作。
2、File对象可以作为参数传递给流的构造函数。
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:字节流通向字符流的桥梁。
3、InputStreamReader是Reader的子类,是FileReader的父类,是字符流的一种。
4、OutputStreamWriter是Writer的子类,是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、字符串的使用
字符转成字节数组时,指定码表。
字节数组转成字符串时,指定码表。
5、IO转换流使用
创建转换流对象时,使用编码。
与字符串共同使用时,保证编码统一。
八、其他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()
printf与println方法支持自动刷新
案例:通过打印流进行文本文件的复制。
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