Java基础之IO


异常处理:

流对象一般会抛出异常,在try的外面进行对象的创建;在try内进行对象引用。


IO流用来处理数据设备之间的数据传输;Java对数据的操作是通过流的方式;Java用于操作流的对象都在IO包中;

 

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

流按流向分为两种: 输入流(读取内存),输出流(写入外设);

  字节流的抽象基类:InputStream,OutputStream。
  字符流的抽象基类:Reader,Writer。

数据是以(二进制)字节形式存在的。字节流可以处理所有对象。

字符流其实就是字节流+编码表;如果要操作文字数据,优先考虑字符流。

 

一、 IO流:

字节流的抽象基类:InputStream , OutputStream;

字符流的抽象基类:ReaderWriter.

 

这些体系中大多的子类都以父类名做后缀,子类名的前缀就是该对象的功能

 

二、 IO字符流:

1.字节流操作中文数据不是特别的方便,所以就出现了转换流。
   转换流的作用就是把字节流转换字符流来使用。


2.转换流其实是一个字符流
字符流 = 字节流 + 编码表

 字节流的抽象基类:InputStream,OutputStream。
  字符流的抽象基类:Reader,Writer。

3.编码表

A:就是由字符和对应的数值组成的一张表
B:常见的编码表
ASCII
ISO-8859-1
GB2312
GBK
GB18030
UTF-8
C:字符串中的编码问题
编码
String -- byte[]
解码
byte[] -- String

4.体系

Reader
|--InputStreamReader
|--FileReader
|--BufferedReader
Writer
|--OutputStreamWriter
|--FileWriter
|--BufferedWriter

 

Writer 

            FileWriter

 

FileWriter往一个文件中写入文字数据;如果文件不存在,则会自动创建;如果存在文件则会覆盖

FileWriter类中常用方法。

  刷新数据flush( ); 返回值为void

  关闭数据流 close();返回值为void

         此方法在关闭流资源之前会先调用flush方法刷新再关闭;flush方法比较:flush可以用多次,但是close方法只能用一次


写入数据 write();返回值为void

续写数据 在构造函数中加入true 可以实现续写;FileWriter(String  FileNameboolean  true)


  读取数据 read();有重载方法,有多种返回类型

Reader 

   FileReader

 FileReader:读取字符数据的流对象,在创建读取对象时,必须要明确被读取的文件,一定要确定该文件是存在的。

 

字符流缓冲区:缓冲区的出现提高了对数据的读写效率。缓冲区要结合流才可以使用。在流的基础上对流的功能进行了增强,(虽然也可以自定义缓冲区)。这样可以使用字符流缓冲区对外提供的方法。

BufferedWriter  BufferedReade

  BufferedWriter


 

BufferedReader 

    LineNumberReader

  BufferedReader类常用方法:

  read( ) 读取数据进缓冲区:可读取 字符型数据;数组数据;换行标记

readLine()读取一个行;返回值类型String

此方法使用读取缓冲区的read方法,将读取的字符进行缓冲并判断换行标记。将标记前的缓冲数据变成字符串返回。


三、IO流字节流

 

字节流与字符流相比而言,处理的数据单元不同;操作的数据文件格式不同,字符流只能操作文本文件,而字节流可以操作媒体文件。

 

字节流基类InputStream , OutputStream;

 

IO字符流常用子类:

 

InputStream 

FileInputStream

FileInputStream:往一个文件中写入文字数据;如果文件不存在,则会自动创建;如果存在文件则会覆盖FileInputStream类中常用方法。

获取字节的个数available()返回int

关闭字节流close( ); 返回值为void

 

关于编解码:编码——看的懂的转换为看不懂的;解码——把看不懂的转换为看得懂的。


四:不同的流

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

(1)可以操作基本类型的数据
(2)流对象名称
DataInputStream
DataOutputStream
内存操作流(理解)
(1)有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
(2)三种
A:ByteArrayInputStream,ByteArrayOutputStream
B:CharArrayReader,CharArrayWriter
C:StringReader,StringWriter
打印流
(1)字节打印流,字符打印流
(2)特点:
A:只操作目的地,不操作数据源
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
D:可以直接操作文件
问题:哪些流可以直接操作文件呢?
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
(3)复制文本文件
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();

标准输入输出流
(1)System类下面有这样的两个字段
in 标准输入流
out 标准输出流
(2)三种键盘录入方式
A:main方法的args接收参数
B:System.in通过BufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
C:Scanner
Scanner sc = new Scanner(System.in);
(3)输出语句的原理和如何使用字符流输出数据
A:原理
System.out.println("helloworld");
PrintStream ps = System.out;
ps.println("helloworld");
B:把System.out用字符缓冲流包装一下使用
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

随机访问流
(1)可以按照文件指针的位置写数据和读数据。
(2)案例:
A:写数据
B:读数据
C:获取和改变文件指针的位置

合并流
(1)把多个输入流的数据写到一个输出流中。
(2)构造方法:
A:SequenceInputStream(InputStream s1, InputStream s2) 
B:SequenceInputStream(Enumeration<? extends InputStream> e) 

序列化流
(1)可以把对象写入文本文件或者在网络中传输
(2)如何实现序列化呢?
让被序列化的对象所属类实现序列化接口。
该接口是一个标记接口。没有功能需要实现。
------------------------------------------------------------------------------------------------------------------------------------------------

练习:

1、把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中?

代码:

package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/*
 * 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
 * 
 * 数据源:
 * a.txt -- 读取数据 -- 字符转换流 -- InputStreamReader
 * 目的地:
 * b.txt -- 写出数据 -- 字符转换流 -- OutputStreamWriter
 */
public class CopyDemo {
public static void main(String[] args) throws IOException {
// 封装数据源
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"a.txt"));
// 封装目的地
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
"b.txt"));


// 读写数据
// 方式1
// int ch = 0;
// while ((ch = isr.read()) != -1) {
// osw.write(ch);
// }


// 方式2
char[] chs = new char[1024];
int len = 0;
while ((len = isr.read(chs)) != -1) {
osw.write(chs, 0, len);
// osw.flush();
}


// 释放资源
osw.close();
isr.close();
}
}

2:复制文本文件(五种方式总结)?

代码:


package IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 复制文本文件
 * 
 * 分析:
 * 复制数据,如果我们知道用记事本打开并能够读懂,就用字符流,否则用字节流。
 * 通过该原理,我们知道我们应该采用字符流更方便一些。
 * 而字符流有5种方式,所以做这个题目我们有5种方式。推荐掌握第5种。
 * 数据源:
 * E:\\a.txt -- FileReader -- BufferdReader
 * 目的地:
 * F:\\b.txt -- FileWriter -- BufferedWriter
 */
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
String srcString = "E:\\a.txt";
String destString = "F:\\b.txt";
method5(srcString, destString);
}

// 字符缓冲流一次读写一个字符串
private static void method5(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}

bw.close();
br.close();
}

// 字符缓冲流一次读写一个字符数组
private static void method4(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}

bw.close();
br.close();
}

// 字符缓冲流一次读写一个字符
private static void method3(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

int ch = 0;
while ((ch = br.read()) != -1) {
bw.write(ch);
}

bw.close();
br.close();
}

// 基本字符流一次读写一个字符数组
private static void method2(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);

char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}

fw.close();
fr.close();
}

// 基本字符流一次读写一个字符
private static void method1(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);

int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}

fw.close();
fr.close();
}
}


3.复制图片(四种方式)?

代码:

package IO;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 复制图片
 * 
 * 分析:
 * 复制数据,如果我们知道用记事本打开并能够读懂,就用字符流,否则用字节流。
 * 通过该原理,我们知道我们应该采用字节流。
 * 而字节流有4种方式,所以做这个题目我们有4种方式。第4种比较好。
 * 
 * 数据源:
 * E:\\a.jpg -- FileInputStream -- BufferedInputStream
 * 目的地:
 * F:\\b.jpg -- FileOutputStream -- BufferedOutputStream
 */
public class CopyImageDemo {
public static void main(String[] args) throws IOException {

// 使用File对象做为参数
File srcFile = new File("E:\\a.jpg");
File destFile = new File("F:\\b.jpg");

method4(srcFile, destFile);
}

// 字节缓冲流一次读写一个字节数组
private static void method4(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));

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

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

// 字节缓冲流一次读写一个字节
private static void method3(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));

int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}

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

// 基本字节流一次读写一个字节数组
private static void method2(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);

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

fos.close();
fis.close();
}

// 基本字节流一次读写一个字节
private static void method1(File srcFile, File destFile) throws IOException {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);

int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}

fos.close();

fis.close();
}
}

4.复制多级文件夹

代码:

package IO;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 需求:复制多极文件夹
 * 
 * 数据源:E:\\java\\duoji\\ddd
 * 目的地:E:\\
 *
 * 分析:
 * A:封装数据源File
 * B:封装目的地File
 * C:判断该File是文件夹还是文件
 * a:是文件夹
 * 就在目的地目录下创建该文件夹
 * 获取该File对象下的所有文件或者文件夹File对象
 * 遍历得到每一个File对象
 * 回到C
 * b:是文件
 * 就复制(字节流)
 */
public class CopyFoldersDemo {
public static void main(String[] args) throws IOException {
// 封装数据源File
File srcFile = new File("E:\\java\\duoji\\ddd");
// 封装目的地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();
}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值