大数据预科班17
复习
- File代表文件或目录--不一定存在--第一次使用时才真正的创建
- RandomAccessFile--支持对文件读写的类--实际看成一个大型的字节数组
IO流
- 流动的数据
- 用于传输数据的API
- 来源、目的地--方向
- Input、Output Stream输入输出流
- 以代码为基准:
- 当数据是从外部流向程序--输入流--读取文件
- 当数据是从程序流向外部--输出流--写入文件
- 根据流的传输方向:传入、传出
- 跟据流的传输形式:字符流、字节流
- 四大基本流--都是抽象类
| 输入流 | 输出流 |
---|
字符流 | Reader | Writer |
字节流 | InputStream | OutputStream |
数据的来源
向TXT文件写入一个字符串
- 输出流、字符流,和文件有关
- OutputStreamWriter下的FileWriter
- 文件不存在时进行创建
- 文件存在时,创建并覆盖
- 无论文件存不存在,都会创建
- write(“”)//数据死在了缓冲区--为了提高效率,java提供了缓冲区,先写到缓缓区,等缓冲区满了之后才会将数据一次性放到目的地
- 解决缓冲区死的数据--write.flush();//冲刷缓冲区、
- 关闭write.close();//关闭流对象--关闭时自动冲刷缓冲区;--流关闭之后,对象依然存在,占用内存--释放流
- writer=null;//释放内存
流的异常
FileWriter fw=null;//外置定义
try{
fw=new FileWriter("E:\\a.txt");
fw.write("aaaa");
fw.flush();//为了防止关流失败导致数据丢失,因此应该提前进行将缓冲输出
}catch(Exception e){
e.printStackTrace();
}finally{
if(null!=wrirter){
try{
writer.close();
}catch(Exception e){
e.printStackTrack();
}finally{
writer=null;
}
}
}
1. try外定义并设置为null,try内初始化
2. 关流之前判断流对象是否为null
3. 为了防止关流失败而导致文件没有释放,需要把流对象强制为为null
4. 为了防止关流失败而导致一部分数据丢失,所以提前进行将数据flushyixia
FileReader
- read返回值为字符所对应的编码--读取到末尾返回-1
- 字符输入流没有缓冲区--每读取一个字符,就可以输出--可以构建字符数组
FileReader reader = new FileReader("E:\\a.tetx");
//自定义缓冲区
char[] cs = new char[5];
//定义变量来记录读取到的字符个数
int len=-1;
while((len=reader.read(cs))!=-1){
}
剪切文件
package com.peng.demo;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* @author kungfu~peng
* @data 2017年9月25日
* @description 剪切文件
*/
public class QjFile {
// 剪切文件
public void jqFile(File fromFile, File toFile) {
FileReader rf = null;
FileWriter fw = null;
// 将文件进行复制
try {
rf = new FileReader(fromFile);
fw = new FileWriter(toFile);
int len = -1;
char[] flush_char = new char[5];
while ((len = rf.read(flush_char)) != -1) {
fw.write(flush_char, 0, len);
}
fw.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != rf) {
try {
rf.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
rf = null;
}
}
if (null != fw) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
fw = null;
}
}
// 将源文件删除
fromFile.delete();
}
// 将原文件进行删除
}
}
1. 问题一:
1. 是否可以将文件删除在关流--不可以;文件操作时,其他不可以操作
2. (假设),删除文件时,流操作也就不存在了
缓冲流Buffer。。。
- 从其他流中获取数据
- BufferedReader(new FileReader())--从字符输入流中读取数据,提供一个缓冲区,允许按行读取
- BufferedWriter--作用不大(写操作已经有缓冲区,现在只是更大一点);重点是newLine()换行符
- 关流--从里到外关流--Stream Alread close
- 只关外面的流--里面的的也会关闭
转换流InputStreamReader/OuputStreamWriter
- OutputStreamWriter--字符流通往字节流的桥梁
- 底层实际上传输的是字节,转换流提供的是将字符转换为字节
- 没有指定编码--使用系统平台码--windows-gbk;可以自定义编码;
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建文件关联的字节输出流对象
FileOutputStream fos = new FileOutputStream(new File("E:\\a.tet"));
// 创建可以把字符转化为字节的转化流对象,并指定编码
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
// 调用转化流,把文字写出去,其实是写到转化流中的缓冲区中
osw.write("您好");
// 关闭流
osw.close();
}
}
/*当调用OutputStreamWriter对象的writer方法时,
会拿着字符到指定的码表中进行查询,
把查到的字符编码值转换成字节数存放到OutputStreamWriter缓冲区中,
最后在调用刷新功能或者关闭流,将缓冲区的字节数据写到指定文件中*/
- InputStreamReader--字节流通往字符流的桥梁
- 底层实际上(FileInputStream)传输的是字节,转换流提供的是将字节转为字符
- 没有指定编码--使用系统平台码;windows-gbk;可以自定义编码;
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建读取文件的字节流对象
FileInputStream in = new FileInputStream(new File("E:\\a.txt"));
// 创建转换流对象
InputStreamReader isr = new InputStreamReader(in, "utf-8");
// 使用转换流读取字节流中的字节
int ch = -1;
while ((ch = isr.read()) != -1) {
System.out.println((char) ch);
}
isr.close();
}
}
/*它使用指定的字符集可以由名称指定或显示给定,或者可以接受平台默认的字符集*/
总结: | | | |
---|
字节->编码表->字符 | 看不懂的->看得懂的 | 需要读。输入流 | InputStreamReader |
字符->编码表->字节 | 看的懂得->看不懂的 | 需要写。输出流 | OutputStreamWriter |
流继承关系
- Writer->OutputStreamWriter->FileWriter
- Reader->InputStreamWriter->FileReader
字节缓冲流
- 字节缓冲输出流BufferedOutputStream
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建基本的字节输出流
FileOutputStream fileOut = new FileOutputStream("a.txt");
// 使用高效的流,把基本的流进行封装,实现速度的提升
BufferedOutputStream out = new BufferedOutputStream(fileOut);
// 写数据
out.write("hello".getBytes());
// 关闭流
out.close();
}
}
- 字节缓冲输入流BufferedInputStream
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建缓冲流对象
FileInputStream fileIn = new FileInputStream(new File("a.txt"));
// 把基本的流包装成高效的流
BufferedInputStream in = new BufferedInputStream(fileIn);
// 读数据
int ch = -1;
while ((ch = in.read()) != -1) {
System.out.println((char) ch);
}
// 关闭
in.close();
}
}
字符缓冲流
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建流
// 基本字符输出流
FileWriter fileOut = new FileWriter("a.txt");
// 把基本的流进行包装
BufferedWriter out = new BufferedWriter(fileOut);
// 写数据
for (int i = 0; i < 5; i++) {
out.write("hello");
out.newLine();// 写入换行符
}
// 关闭流
out.close();
}
}
public class QjFile {
public static void main(String[] args) throws Exception {
// 创建流
BufferedReader in = new BufferedReader(new FileReader("a.txt"));
// 读数据
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
// 关闭流
in.close();
}
}
流的操作规律
- 明确一:要操作的数据是数据源还是数据目的
- 源:InputStream Reader
- 目的:OutputStream Writer
- 先根据需求明确要读,还是要写
- 明确二:要操作的数据是字节还是文本
- 明确三:吗明确数据所在的具体设备
- 源设备
- 硬盘:文件 以File开头
- 内存:数组,字符串
- 键盘:System.in
- 网络:Socket
- 目的设备
- 硬盘:文件 File
- 内存:数组,字符串
- 屏幕:System.out
- 网络:Socket
- 明确四:是否需要额外功能呢?
- 额外功能:
- 转换吗? 转换流 InputStreamReader OutputStreamWriter
- 高效吗? 缓冲区对象,BufferedInputStream/BufferedOutputStream BufferedWriter/BufferedReader
字节流
- 不存在缓冲区字
- close关流,释放资源
- 字节流可以读取任意文件
- java的原生的流(字符流)对office组件支持的不好---POI操作组件
练习
package com.peng.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* @author kungfu~peng
* @data 2017年9月25日
*/
public class QjFile {
public static void main(String[] args) throws Exception {
changeCode();
}
// 改变文件的编码
public static void changeCode() throws Exception {
// 创建新文件
File toFile = new File("E:\\b.txt");
File fromFile = new File("E:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
toFile), "utf-8");
// 读取源文件
InputStreamReader isr = new InputStreamReader(new FileInputStream(
fromFile), "gbk");
int s = -1;
char[] data = new char[10];
// 文件a的内容复制进b文件
while ((s = isr.read(data)) != -1) {
osw.write(data);
}
isr.close();
osw.close();
// 将a文件删除
fromFile.delete();
// 将文件b改名
toFile.renameTo(new File("E:\\c.txt"));
}
}
系统流/标准流
- 系统都是字节流
- System.out()标准输出流
- System.in()标准输入流
- System.err()标注错误流
- out和err再使用时没有任何差别,只是在输出结果有颜色差别;正常结果--out,错误结果--err
- 线程不安全--out和err--同行或上下位置变化
练习
- 用BufferedReader和System.in来实现输入和获取一行数据
package com.peng.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author kungfu~peng
* @data 2017年9月25日
*/
public class FileTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(br.readLine().toString());
br.close();
}
}
/*关闭时in也关闭了,不能二次获取*/
打印流
- PrintStream/PrintWriter--可以传入一个输出流,更改格式后输出
- print(XX xx)没有无参函数
- println(XX xx)有有参函数
- 注意:除char[]引用数据类型打印字符串,其他的都是打印地址
合并流
- 提出:增强用户体验
- SequenceInputStream(InputStream i1,InputStream i2);
- SequenceInputStream(Enumeration e);//利用Vector--elements
- 只有合并输入流,没有合并输出流
- 不能控制字符集
package com.pneg.io2;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/**
* @author kungfu~peng
* @data 2017年11月8日
* @description
*/
public class SquenceStreamDemo {
public static void main(String[] args) throws Exception {
// 分别出创建输入流来指向要合并的文件
FileInputStream in1 = new FileInputStream("a.txt");
FileInputStream in2 = new FileInputStream("b.txt");
FileInputStream in3 = new FileInputStream("c.txt");
// 创建一个Vector对象存入流
Vector<InputStream> ins = new Vector<InputStream>();
ins.add(in1);
ins.add(in2);
ins.add(in3);
// 需要将集合转化为一个枚举对象
Enumeration<InputStream> e = ins.elements();
// 创建合并流对象
SequenceInputStream sis = new SequenceInputStream(e);
// 读取数据
byte[] data = new byte[1024];
int len = -1;
while ((len = sis.read(data)) != -1) {
System.out.println(new String(data, 0, len));
}
}
}
- 练习:文件切块
- 文件越多,打开越慢
- 创建足够多的文件放置
- 文件的存储位置--记录
操作内存的类
- StringReader
- StringWriter
- CharArrayOutputStream
- ByteArrayOutputStream