您的位置:首页 > 编程语言 > Java开发

java基础--IO

2015-08-11 16:00 459 查看
一、File类

1、IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件

2、构造方法

A:File file = new File("e:\\demo\\a.txt"); 根据一个路径得到File对象

B:File file = new File("e:\\demo","a.txt"); 根据一个目录和一个子文件/目录得到File对象

C:File file = new File(file,"a.txt")); 根据一个父File对象和一个子文件/目录得到File对象

3、File类的功能

A:创建功能

public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了

public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了

public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来

B:删除功能

public boolean delete() 删除

C:重命名功能

public boolean renameTo(File dest) 如果路径名相同,就是改名。如果路径名不同,就是改名并剪切

D:判断功能

public boolean isDirectory():判断是否是目录

public boolean isFile():判断是否是文件

public boolean exists():判断是否存在

public boolean canRead():判断是否可读

public boolean canWrite():判断是否可写

public boolean isHidden():判断是否隐藏

E:获取功能

public String getAbsolutePath():获取绝对路径

public String getPath():获取相对路径

public String getName():获取名称

public long length():获取长度。字节数

public long lastModified():获取最后一次的修改时间,毫秒值

F:高级获取功能

public String[] list():获取指定目录下的所有文件或者文件夹的名称数组

public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组

G:过滤器功能

文件名称过滤器 FilenameFilter 接口 重写 public boolean accept(File dir, String name)

4、案例

A:获取制定文件后缀名称,并输出此文件名称

public class Test {
public static void main(String[] args) {
// 封装e判断目录
File file = new File("e:\\");

// 获取该目录下所有文件或者文件夹的String数组
// public String[] list(FilenameFilter filter)
String[] strArray = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile() && name.endsWith(".jpg");
}
});

// 遍历
for (String s : strArray) {
System.out.println(s);
}
}
}


二、IO流

1、概括

1.IO用于在设备间进行数据传输的操作

上传文件和下载文件

2.分类

A:流向

输入流读取数据

输出流写出数据

B:数据类型

字节流

字节输入流和字节输出流

字符流

字符输入流和 字符输出流

3.常用基类

A.字节流的抽象基类

InputStream,OutputStream

子类:FileInputStream,FileOutputStream

BufferedInputStream,BufferedOutputStream

B.字符流的抽象基类

Reader,Writer

子类:FileReader,FileWriter

BufferedReader,BufferedWriter

2、字节流

(1).FileOutputStream写出数据

A.操作步骤

a.创建字节输出流对象(创建如:FileOutputStream fos = new FileOutputStream("fos.txt", true) 可实现实现数据的追加写入)

b.调用write()方法

c.,释放资源

B.代码体现

FileOutputStream fos = new FileOutputStream("fos.txt");

fos.write("hello".getBytes());

fos.close();


(2).FileInputStream读取数据

A.操作步骤

a.创建字节输入流对象

b.调用read()方法

c.释放资源

B.代码体现

FileInputStream fis = new FileInputStream("fos.txt");

//方式1
int by = 0;
while((by=fis.read())!=-1) {
System.out.print((char)by);
}

//方式2
byte[] bys = new byte[1024];
int len = 0;
while((len=fis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}

fis.close();


(3).案列:复制文本文件

/*
* 需求:把c盘下的a.txt的内容复制到d盘下的b.txt中
*
* 数据源:
* 		c:\\a.txt	--	读取数据--	FileInputStream
* 目的地:
* 		d:\\b.txt	--	写出数据	--	FileOutputStream
*/
public class Test {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream("c:\\a.txt");
// 封装目的地
FileOutputStream fos = new FileOutputStream("d:\\b.txt");

// 方式一 太慢不采用
// int by = 0;
// while ((by = fis.read()) != -1) {
// fos.write(by);
// }

// 方式二
byte[] b = new byte[1024];
int len = 0;

while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}

// 释放资源
fos.close();
fis.close();
}
}


(4)字节缓冲区流

A:BufferedOutputStream

B:BufferedInputStream

(5)案例:复制mp3文件

/*
* 需求:把c盘下的a.txt的内容复制到d盘下的b.txt中
*
* 数据源:
* 		c:\\a.mp3	--	读取数据--	FileInputStream
* 目的地:
* 		d:\\b.mp3	--	写出数据	--	FileOutputStream
*/
public class Test {
public static void main(String[] args) throws IOException {
// 封装数据源
BufferedInputStream  bis = new BufferedInputStream(new FileInputStream("c:\\a.mp3"));
// 封装目的地
BufferedOutputStream  bos = new BufferedOutputStream(new FileOutputStream("d:\\b.mp3"));

byte[] b = new byte[1024];
int len = 0;

while ((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
}

// 释放资源
bis.close();
bos.close();
}
}


3、字符流

(1)似字节流,只是用的对象不一样。字节流一般用于图片、mp3、影片等读写;而字符流用于文本文件的读写

(2)读数据方式:

int read():一次读取一个字符

int read(char[] chs):一次读取一个字符数组

(3)字符缓冲流的特殊方法:

BufferedWriter:

public void newLine():根据系统来决定换行符

BufferedReader:

public String readLine():一次读取一行数据 ;包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

4、转换流

(1)转换流的作用就是把字节流转换字符流来使用

(2)转换流其实是一个字符流

字符流 = 字节流 + 编码表

(3)编码表

A.就是由字符和对应的数值组成的一张表

B.常见的编码表

ASCII、ISO-8859-1、GB2312、GBK、GB18030、UTF-8

(4)IO流中编码

A:OutputStreamWriter

OutputStreamWriter(OutputStream os):默认编码,GBK

OutputStreamWriter(OutputStream os,String charsetName):指定编码

B:InputStreamReader

InputStreamReader(InputStream is):默认编码,GBK

InputStreamReader(InputStream is,String charsetName):指定编码

(5)读数据方式

int read():一次读取一个字符

int read(char[] chs):一次读取一个字符数组

5、IO流小结

(1)io流结构图

|--字节流

|--字节输入流

InputStream

int read():一次读取一个字节

int read(byte[] bys):一次读取一个字节数组

|--FileInputStream

|--BufferedInputStream

|--字节输出流

OutputStream

void write(int by):一次写一个字节

void write(byte[] bys,int index,int len):一次写一个字节数组的一部分

|--FileOutputStream

|--BufferedOutputStream

|--字符流

|--字符输入流

Reader

int read():一次读取一个字符

int read(char[] chs):一次读取一个字符数组

|--InputStreamReader

|--FileReader

|--BufferedReader

String readLine():一次读取一个字符串

|--字符输出流

Writer

void write(int ch):一次写一个字符

void write(char[] chs,int index,int len):一次写一个字符数组的一部分

|--OutputStreamWriter

|--FileWriter

|--BufferedWriter

void newLine():写一个换行符

void write(String line):一次写一个字符串

(2)案列

A.复制多级文件夹

public class CopyFoldersDemo {
public static void main(String[] args) throws IOException {
// 封装数据源File
File srcFile = new File("E:\\JavaSE\\demos");
// 封装目的地File
File destFile = new File("E:\\");

// 复制文件夹的功能
copyFolder(srcFile, destFile);
}

//复制文件和目录
private static void copyFolder(File srcFile, File destFile)
throws IOException {
// 判断该File是文件夹还是文件
if (srcFile.isDirectory()) {
// 文件夹
File newFolder = new File(destFile, srcFile.getName());
newFolder.mkdir();

// 获取该File对象下的所有文件或者文件夹File对象
File[] fileArray = srcFile.listFiles();
for (File file : fileArray) {
copyFolder(file, newFolder);
}
} else {
// 文件
File newFile = new File(destFile, srcFile.getName());
copyFile(srcFile, newFile);
}
}

//复制数据
private static void copyFile(File srcFile, File newFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(newFile));

byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}

bos.close();
bis.close();
}
}


B、用Reader模拟BufferedReader的readLine()功能

/*
* 用Reader模拟BufferedReader的readLine()功能
*
* readLine():一次读取一行,根据换行符判断是否结束,只返回内容,不返回换行符
*/
public class MyBufferedReader {
private Reader r;

public MyBufferedReader(Reader r) {
this.r = r;
}

/*
* 写一个方法,返回值是一个字符串。
*/
public String readLine() throws IOException {

StringBuilder sb = new StringBuilder();

// 做这个读取最麻烦的是判断结束,但是在结束之前应该是一直读取,直到-1

/*
hello
world
java

104101108108111
119111114108100
1069711897
*/

int ch = 0;
while ((ch = r.read()) != -1) { //104,101,108,108,111
if (ch == '\r') {
continue;
}

if (ch == '\n') {
return sb.toString(); //hello
} else {
sb.append((char)ch); //hello
}
}

// 为了防止数据丢失,判断sb的长度不能大于0
if (sb.length() > 0) {
return sb.toString();
}

return null;
}

/*
* 先写一个关闭方法
*/
public void close() throws IOException {
this.r.close();
}
}


/*
* 测试MyBufferedReader的时候,你就把它当作BufferedReader一样的使用
*/
public class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
MyBufferedReader mbr = new MyBufferedReader(new FileReader("my.txt"));

String line = null;
while ((line = mbr.readLine()) != null) {
System.out.println(line);
}

mbr.close();

// System.out.println('\r' + 0); // 13
// System.out.println('\n' + 0);// 10
}
}


6、其他流

(1)数据操作流(操作基本类型数据的流)

A、可以操作基本类型的数据

B、流对象名称

DataInputStream

DataOutputStream

(2)内存操作流

A、有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流

用于处理临时存储信息的,程序结束,数据就从内存中消失

B、三种

a:ByteArrayInputStream,ByteArrayOutputStream

b:CharArrayReader,CharArrayWriter

c:StringReader,StringWriter

(3)打印流

A、字节打印流,字符打印流

B、特点:

a.只操作目的地,不操作数据源

b.可以操作任意类型的数据

c.如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新

d.可以直接操作文件

C、启动自动刷新

PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);

println() 其实等价于于 bw.write();bw.newLine();bw.flush();

(4)标准输入输出流

A、System类下面有这样的两个字段

in 标准输入流

out 标准输出流

B、三种键盘录入方式

a.main方法的args接收参数

b.System.in通过BufferedReader进行包装

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

c.Scanner

Scanner sc = new Scanner(System.in);

(5)随机访问流

A、RandomAccessFile类不属于流,是Object类的子类

但它融合了InputStream和OutputStream的功能

可以按照文件指针的位置写数据和读数据

B、方法:

public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模式

模式有四种,我们最常用的一种叫"rw",这种方式表示我既可以写数据,也可以读取数据

(6)合并流

A、把多个输入流的数据写到一个输出流中

B、构造方法

a.SequenceInputStream(InputStream s1, InputStream s2)

b.SequenceInputStream(Enumeration<? extends InputStream> e)

(7)序列化流

A、概念

序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象 -- 流数据(ObjectOutputStream)

反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 -- 对象(ObjectInputStream)

B、如何实现序列化呢?

让被序列化的对象所属类实现序列化接口 Serializable

该接口是一个标记接口。没有功能需要实现。

C、注意问题

把数据写到文件后,在去修改类会产生一个问题

如何解决该问题呢?

在类文件中,给出一个固定的序列化id值

而且,这样也可以解决黄色警告线问题

D、面试题

什么时候序列化?

如何实现序列化?

什么是反序列化?

(8)Properties

A、是一个集合类,Hashtable的子类。属性集合类。是一个可以和IO流相结合使用的集合类

B、特有功能

a.public Object setProperty(String key,String value) 添加元素

b.public String getProperty(String key) 获取元素

c.public Set<String> stringPropertyNames() 获取所有的键的集合

C、和IO流结合的方法

a.把键值对形式的文本文件内容加载到集合中

public void load(Reader reader)

public void load(InputStream inStream)

b.把集合中的数据存储到文本文件中

public void store(Writer writer,String comments)

public void store(OutputStream out,String comments)

D、案例

根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100

/*
* 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么。
* 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其实为”100”
*
* 分析:
* 		A:把文件中的数据加载到集合中
* 		B:遍历集合,获取得到每一个键
* 		C:判断键是否有为"lisi"的,如果有就修改其值为"100"
* 		D:把集合中的数据重新存储到文件中
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException {
// 把文件中的数据加载到集合中
Properties prop = new Properties();
Reader r = new FileReader("user.txt");
prop.load(r);
r.close();

// 遍历集合,获取得到每一个键
Set<String> set = prop.stringPropertyNames();
for (String key : set) {
// 判断键是否有为"lisi"的,如果有就修改其值为"100"
if ("lisi".equals(key)) {
prop.setProperty(key, "100");
break;
}
}

// 把集合中的数据重新存储到文件中
Writer w = new FileWriter("user.txt");
prop.store(w, null);
w.close();
}
}


(9)NIO(了解)

A、JDK4出现的NIO,对以前的IO操作进行了优化,提供了效率,但是目前还不是大范围的使用。大部分我们看到的还是以前的IO

B、JDK7的NIO的使用

Path:路径

Paths:通过静态方法返回一个路径

public static Path get(URI uri)

Files:提供了静态方法供我们使用

public static long copy(Path source,OutputStream out):复制文件

public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)

C、案列

public class NIODemo {
public static void main(String[] args) throws IOException {
//复制文件
Files.copy(Paths.get("ByteArrayStreamDemo.java"), new FileOutputStream("Copy.java"));

ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
//把集合中的元素复制到文件中
Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: