8. IO技术
1. File类
File(掌握)
1、IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件
2、构造方法
A:File file = new File("e:\\demo\\a.txt");
B:File file = new File("e:\\demo","a.txt");
C:File file = new File("e:\\demo");
File file2 = new File(file,"a.txt");
3、File类的功能
(1)、文件名
getName() 文件名、路径名,返回名称
getPath()路径名,如果是绝对路径,返回完整路径,否则相对路径
getAbsoluteFile() 绝对路径所对应的File对象
getAbsolutePath() 绝对路径名
getParent() 父目录 ,相对路径的父目录,可能为null 如删除本身后的结果
(2)、判断信息
exists() canWrite() canRead() isFile() isDirectory()
isAbsolute():消除平台差异,ie以盘符开头,其他以/开头
(3)、长度 字节数 不能读取文件夹的长度length()
(4)、创建、删除
createNewFile() 不存在创建新文件,存在返回false,创建文件名时含有con系统关键字,则创建失败
delete() 删除文件
static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
staticcreateTempFile(前缀3个字节长,后缀默认.temp,目录)
deleteOnExit() 退出虚拟机删除,常用于删除临时文件
(5)、操作目录
mkdir() 创建目录,必须确保父目录存在,如果不存在,创建失败
mkdirs() 创建目录,如果父目录链不存在一同创建
list() 返回文件|目录 名字符串形式
listFiles()
static listRoots() 根路径
|
/**
* 两个常量
* 1、路径分隔符 ;
* 2、名称分隔符 /(windows) /(linux 等)
*/
public class Demo01 {
public static void main(String[] args) {
System.out.println(File.pathSeparator);
System.out.println(File.separator);
//路径表示形式
String path ="E:\\xp\\test\\2.jpg";
path="E:"+File.separator+"xp"+File.separator+"test"+File.separator+"2.jpg";
//推荐方式
path="E:/xp/test/2.jpg";
}
}
|
/**
* 相对路径与绝对路径构造 File对象
* 1、相对路径
File(String parent, String child) ==>File("E:/xp/test","2.jpg")
File(File parent, String child) ==> File(new File("E:/xp/test"),"2.jpg")
2、绝对路径
File(String name);
* @author Administrator
*
*/
public class Demo02 {
/**
* @param args
*/
public static void main(String[] args) {
String parentPath ="E:/xp/test";
String name ="2.jpg";
//相对路径
File src =new File(parentPath,name);
src =new File(new File(parentPath),name);
//输出
System.out.println(src.getName());
System.out.println(src.getPath());
//绝对路径
src =new File("E:/xp/test/2.jpg");
System.out.println(src.getName());
System.out.println(src.getPath());
//没有盘符: 以 user.dir构建
src =new File("test.txt");
src =new File(".");
System.out.println(src.getName());
System.out.println(src.getPath());
System.out.println(src.getAbsolutePath());
}
}
|
/**
* 常用方法:
1、文件名
getName() 文件名、路径名
getPath()路径名
getAbsoluteFile() 绝对路径所对应的File对象
getAbsolutePath() 绝对路径名
getParent() 父目录 ,相对路径的父目录,可能为null 如. 删除本身后的结果
2、判断信息
exists()
canWrite()
canRead()
isFile()
isDirectory()
isAbsolute():消除平台差异,ie以盘符开头,其他以/开头
3、长度 字节数 不能读取文件夹的长度
length()
4、创建、删除
createNewFile() 不存在创建新文件,存在返回false
delete() 删除文件
static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
staticcreateTempFile(前缀3个字节长,后缀默认.temp,目录)
deleteOnExit() 退出虚拟机删除,常用于删除临时文件
* @author Administrator
*
*/
public class Demo03 {
/**
* @param args
*/
public static void main(String[] args) {
test2();
try {
test3();
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件操作失败");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//创建删除文件
public static void test3() throws IOException, InterruptedException{
//createNewFile() 不存在创建新文件
//String path="E:/xp/test/con"; //con系统关键字
String path="E:/xp/test/200.jpg";
//String path="E:/xp/test/1.jpg";
File src =new File(path);
if(!src.exists()){
boolean flag =src.createNewFile();
System.out.println(flag?"成功":"失败");
}
//删除文件
boolean flag =src.delete();
System.out.println(flag?"成功":"失败");
//static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
//static createTempFile(前缀3个字节长,后缀默认.temp,目录)
File temp= File.createTempFile("tes", ".temp",new File("e:/xp/test"));
Thread.sleep(10000);
temp.deleteOnExit(); //退出即删除
}
//2、判断信息
//3、长度 length()
public static void test2(){
//String path ="2.txt";
String path="E:/xp/test/200.jpg";
//String path="E:/xp/test/200.jpg";
File src =new File(path);
//是否存在
System.out.println("文件是否存在:"+src.exists());
//是否可读 写 canWrite() canRead()
System.out.println("文件是否可写"+src.canWrite());
System.out.println("============");
//isFile()
//isDirectory()
if(src.isFile()){
System.out.println("文件");
}else if(src.isDirectory()){
System.out.println("文件夹");
}else{
System.out.println("文件不存在");
}
System.out.println("是否为绝对路径"+src.isAbsolute());
System.out.println("长度为:"+src.length());
}
//1、名称
public static void test1(){
//File src =new File("E:/xp/test/2.jpg");
//建立联系
File src =new File("2.txt");
System.out.println(src.getName()); //返回名称
System.out.println(src.getPath()); //如果是绝对路径,返回完整路径,否则相对路径
System.out.println(src.getAbsolutePath());//返回绝对路径
System.out.println(src.getParent());//返回上一级目录,如果是相对,返回null
}
}
|
/**
* 5、操作目录
mkdir() 创建目录,必须确保 父目录存在,如果不存在,创建失败
mkdirs() 创建目录,如果父目录链不存在一同创建
list() 文件|目录 名字符串形式
listFiles()
static listRoots() 根路径
* @author Administrator
*
*/
public class Demo04 {
/**
* @param args
*/
public static void main(String[] args) {
String path ="E:/xp/test/";
File src =new File(path); //文件夹
if(src.isDirectory()){ //存在并且为目录
System.out.println("======子目录|文件名===");
String[] subNames =src.list();
for(String temp:subNames){
System.out.println(temp);
}
System.out.println("=====子目录|文件File对象====");
File[] subFiles =src.listFiles();
for(File temp:subFiles){
System.out.println(temp.getAbsolutePath());
}
System.out.println("=====子文件.java对象====");
//命令设计模式
subFiles =src.listFiles(new FilenameFilter(){
@Override
/**
* dir 代表src
*/
public boolean accept(File dir, String name) {
//System.out.println(dir.getAbsolutePath());
return new File(dir,name).isFile()&&name.endsWith(".java");
}
});
for(File temp:subFiles){
System.out.println(temp.getAbsolutePath());
}
}
}
public static void test1(){
String path ="E:/xp/test/parent/p/test";
File src =new File(path);
//src.mkdir();
src.mkdirs();
}
}
|
/**
* 输出子孙级目录|文件的名称(绝对路径)
* 1、listFiles()
* 2、递归
*
* static listRoots() 根路径
*
*/
public class Demo05 {
/**
* @param args
*/
public static void main(String[] args) {
String path ="E:/xp/test";
File parent =new File(path);
//printName(parent);
File[] roots =File.listRoots();
System.out.println(Arrays.toString(roots));
for(File temp:roots){
//printName(temp);
}
}
/**
* 输出路径
*/
public static void printName(File src){
if(null==src || !src.exists()){
return ;
}
System.out.println(src.getAbsolutePath());
if(src.isDirectory()){ //文件夹
for(File sub:src.listFiles()){
printName(sub);
}
}
}
}
|
2. 原理与概念
一、概念
流:流动 、流向 从一端移动到另一端 源头与目的地
程序 与 文件|数组|网络连接|数据库 ,以程序为中心
二、IO流分类
1、流向: 输入流与输出流
2、数据:字节流:二进制,可以一切文件 包括 纯文本 doc 音频、视频等等
字符流:文本文件,只能处理纯文本
3、功能:节点:包裹源头
处理:增强功能,提供性能
三、字符流与字节流 (重点) 与文件
1、字节流
输入流:InputStream read(byte[] b) 、read(byte[] b, int off, int len) +close()
FileInputStream()
输出流:OutputStream write(byte[] b) write(byte[] b, int off, int len) +flush() +close()
FileOutputStream
2、字符流
输入流:Reader read(char[] cbuf) read(char[] cbuf, int off, int len) +close()
FileReader()
输出流:Writer write(char[] cbuf) write(char[] cbuf, int off, int len) +flush() +close()
write(String str, int off, int len)
FileWriter()
四、操作
1、举例:搬家 -->读取文件
1)、关联房子 --->建立与文件联系
2)、选择搬家 --->选择对应流
3)、搬家 -->读取|写出
a)、卡车大小 --->数组大小
b)、运输 -->读取、写出
4)、打发over -->释放资源
2、操作
1)建立联系
2)选择流
3)操作 数组大小+read 、write
4)释放资源
注意:
a:如果我们没有明确说明按照什么分,默认按照数据类型分。
b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。
4. 字符流
字符流:只能处理 纯文本,全部为可见字符 .txt .html
节点流 Reader FileReader
Writer FileWriter
一、纯文本读取
1、建立联系
2、选择流 Reader FileReader
3、读取 char[] flush =new char[1024];
4、关闭
二、纯文本写出
1、建立联系
2、选择流 Writer FileWriter
3、读取 write(字符数组,0,长度)+flush
write(字符串)
append(字符|字符串)
4、关闭
5. 处理流
处理流:增强功能、提供性能,节点流之上
一、缓冲流
1)、字节缓冲流
BufferedInputStream
BufferedOutputStream
2)、字符缓冲流
BufferedReader readLine()
BufferedWriter newLine()
二、转换流: 字节流 转为字符流 处理乱码(编码集、解码集)
1、编码与解码概念
编码: 字符 ---编码字符集>二进制
解码 : 二进制 --解码字符集-> 字符
2、乱码:
1)编码与解码的字符集不统一
2)字节缺少,长度丢失
3、文件乱码
InputStreamReader(字节输入流,"解码集")
OutputStreamWriter(字符输出流,"编码集")
6. 其他流
一、节点流
1、字节数组 字节 节点流
输入流:ByteArrayInputStream read(byte[] b, int off, int len) + close()
输出流:ByteArrayOutputStream write(byte[] b, int off, int len) +toByteArray()新增方法 不要使用多态
二、处理流
1、基本类型+String 保留数据+类型
输入流:DataInputStream readXxx
输出流:DataOutputStream writeXxx
2、引用类型 (对象) 保留数据+类型
反序列化 输入流:ObjectInputStream readObject()
序列化 输出流:ObjectOutputStream writeObject()
注意:
1)、先序列化后反序列化;反序列化顺序必须与序列化一致
2)、不是所有的对象都可以序列化, java.io.Serializable
不是所有的属性都需要序列化,transient
3、打印流 PrintStream println() print()
4、三个常量 : System.in /out/err System.setIn() setOut() setErr()
IO流概述
1、IO流概述
(1)用来处理设备(硬盘,控制台,内存)间的数据。
(2)java中对数据的操作都是通过流的方式。
(3)java用于操作流的类都在io包中。
(4)按照流操作的数据的类型不同:分为字节流和字符流。字符流是为了方便中文的操作而来的。
(5)按照流的流向不同分为:输入流,输出流
2、概念
流:流动 、流向 从一端移动到另一端 源头与目的地
程序 与 文件|数组|网络连接|数据库 ,以程序为中心
3、IO流分类
a、流向: 输入流与输出流
b、数据:字节流:二进制,可以一切文件 包括 纯文本 doc 音频、视频等等
字符流:文本文件,只能处理纯文本
c、功能:节点:包裹源头
处理:增强功能,提供性能
IO流常用基类
IO流常用基类:
(1)字节流
输出字节流:OutputStream:字节写入流抽象类
|--->FileOutputStream:
字节写入流
|--->BufferedOutputStream:
字节写入流缓冲区
|--->PrintStream:
打印流
输入字节流:InputStream:字节读取流抽象类
|--->FileInputStream:
字节读取流
|--->BufferedInputStream:
字节读取流缓冲区
(2)字符流
输出字符流:Writer:字符写入流的抽象
|--->FileWriter:
字符写入流
|--->BufferedWriter:
字符写入流缓冲区
|--->OutputStreamWriter:
字符通向字节的转换流(涉及键盘录入时用)
|--->OutputStreamWriter:
打印流,可处理各种类型的数据
输入字符流:Reader: 字符读取流的抽象类
|--->FileReader:
字符读取流
|--->LineNumberReader:
跟踪行号的缓冲字符读取流
|--->BufferedReader:
字符读取流缓冲区
--->InputStreamReader:
字节通向字符的转换流(涉及键盘录入时用)
(3)IO流常用基类方法摘要:
**字节写入流:OutputStream:
void close() 关闭此输出流并释放与此流有关的所有系统资源。
void flush()刷新此输出流并强制写出所有缓冲的输出字节。
abstract void write(int b) 将指定的字节写入此输出流。
void write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
**字节读取流:InputStream:
void close() 关闭此输入流并释放与该流关联的所有系统资源。
int available() (特有方法!!)
返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
abstract int read() 从输入流中读取数据的下一个字节。
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组。
long skip(long n) 跳过和丢弃此输入流中数据的 n 个字节。
**字符写入流:Writer:
abstract void close() 关闭此流,但要先刷新它。
abstract void flush() 刷新该流的缓冲。
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分。
**字符读取流:Reader:
abstract void close() 关闭该流并释放与之关联的所有资源。
int read() 读取单个字符。
int read(char[] cbuf) 将字符读入数组
abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
long skip(long n) 跳过字符。
字节流基类的子类
IO流常用字节流基类的子类:
**写入流:
(1)FileOutputStream:
**构造方法:
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append)
创建一个向具有指定 name 的文件中写入数据的输出文件流。
FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
**方法摘要:
public void flush()
void close() 关闭此文件输出流并释放与此流有关的所有系统资源。
void write(int b) 将指定字节写入此文件输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
void write(int b) 将指定字节写入此文件输出流。
(2)BufferedOutputStream:
**构造方法:
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
**方法摘要:
void flush() 刷新此缓冲的输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。
void write(int b) 将指定的字节写入此缓冲的输出流。
(3)PrintStream:打印流,可将各种类型的数据原样打印,有自动刷新功能
**构造方法:
PrintStream(String fileName)
创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(File file)
创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(OutputStream out)
创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush) (当autoFlush为true时具有自动刷新功能)
创建新的打印流。
**方法摘要:
PrintStream append(char c)
将指定字符添加到此输出流。
void close()
关闭流。
void flush()
刷新该流的缓冲。
void print(各种类型的数据:)
打印各种类型的数据
void println(各种类型的数据:):自动换行
打印各种类型的数据
void write(byte[] buf, int off, int len)
将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。
void write(int b)
将指定的字节写入此流。
**读取流:
(1)FileInputStream:
**构造方法:
FileInputStream(String name)
通过打开一个到实际文件的连接来创建一个 FileInputStream,
该文件通过文件系统中的路径名 name 指定。
FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,
该文件通过文件系统中的 File 对象 file 指定。
**方法摘要:
int available() (字节读取流特有方法!!!)
返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
int read()
从此输入流中读取一个数据字节。
int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
int read(byte[] b, int off, int len)
从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
long skip(long n)
从输入流中跳过并丢弃 n 个字节的数据。
(2)BufferedInputStream:
**构造方法:
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream(InputStream in, int size)
创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
**方法摘要:
int available() (字节读取流特有方法!!!)
返回可以从此输入流读取(或跳过)、且不受此输入流接下来的方法调用阻塞的估计字节数。
int read()
参见 InputStream 的 read 方法的常规协定。
int read(byte[] b, int off, int len)
从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
long skip(long n)
参见 InputStream 的 skip 方法的常规协定。
字符流基类的子类
字符流
字符流:
(1)在硬盘上创建一个文件并写入信息
用字符写入流:FileWriter
FileWriter fw = new FileWriter("g:\\filewriter.txt");
fw.write("输入信息");
fw.write("也可以写入字符数组".toCharArray());
fw.flush();
fw.close();
(2)在原有文件上续写数据
FileWriter fw = new FileWriter("g:\\filewriter.txt",true);
fw.write("还可以续写信息");
fw.write("也可以写入字符数组".toCharArray());
fw.flush();
fw.close();
(3)读取硬盘上的文本文件,并将数据打印在控制台
FileReader fr = new FileReader("g:\\filewriter.txt");
第一种读取方法:一个一个字节的读
int ch = 0;
ch = fr.read();
sop((char)ch);
fr.close();
第二种读取方法:利用数组来提高效率
char[] buf = new char[1024];
int len = 0;
while((len = fr.read(buf))!=-1){
sop(new String(buf,0,len));
}
fr.close();
(4)拷贝文本文件
利用缓冲区提高数据读写效率
(无缓冲区就相当于一滴一滴的喝水,有缓冲区就相当于一杯一杯的喝水)
BufferedReader bufr = new BufferedReader(new FileReader("g:\\filewriter.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\\copyfilewriter.txt"));
String line = null;
while((line = bufr.readLine())!=null)
{
burw.write(line);
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
字节流
字节流:字节流写入时没有刷新
(1)在硬盘上创建一个文件并写入信息(字节流写入时没有刷新)
FileOutputStream fos = new FileOutputStream("g:\\filestream.txt");
fos.write(97);//写入一个字节,int:97代表写入char:a
fos.write("也可以写入字节数组".getBytes());//通常使用此种方式写入,直观!
fos.close();
(2)在硬盘已有文件上续写数据(字节流写入时没有刷新)
FileOutputStream fos = new FileOutputStream("g:\\filestream.txt",true);
fos.write("创建字节写入流时,传进去一个true参数就可以继续写入信息".getBytes());
fos.close();
(3)读取硬盘上的文件
FileInputStream fis = new FileInputStream("g:\\filestream.txt");
**第一种读法:一个字节一个字节的读(此种读法慢)
int ch = 0;
while((ch = fis.read())!=-1)
{
sop((char)ch);
}
**第一种读法:利用字节数组读(此种读法效率有一定提高)
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read())!=-1)
{
sop(new String(buf,0,len));
}
(4)拷贝字节文件,如图片或者MP3或者电影
**第一种拷贝:不带缓冲区(慢,还是效率问题)
FileInputStream fis = new FileInputStream("g:\\1.mp3");
FileOutputStream fos = new FileOutputStream("g:\\copy1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf))!=-1)
{
fos.(buf,0,len);//字节流写入无需刷新
}
fis.close();
fos.close();
**第二种拷贝:带缓冲区,高效
BufferedInputStream bufi = new BufferedInputStream(new FileInputStream("g:\\1.mp3"));
BufferedOutputStream bufo = new BufferedOutputStream(new FileOutputStream("g:\\copy1.mp3"));
int ch = 0;
while((ch = bufi.read())!=-1)
{
bufo.write(ch);
}
bufi.close();
bufo.close();
转换流
转换流:
(1)读取一个键盘录入
InputStream in = System.in;//创建一个键盘录入流,流不关则可以一直录入
int by1 = in.read();//一次读一个字节
int by2 = in.read();//一次读一个字节
sop(by1);//假设键盘录入的是abcd,则打印a
sop(by2);//假设键盘录入的是abcd,则打印b
in.close();
(2)键盘录入一行数据打印一行数据,如果录入的是over则结束录入
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true){
int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n'){
String line = sb.toString();
if("over".equals(line))
break;
sop(line.toUpperCase());//输出大写
sb.delete(0.sb.length());//清除上一行录入的数据
}else{
sb.append((char)ch);
}
in.close();
(3)发现需求2中其实就是读一行的原理,故引入字节通向字符的桥梁:InputStreamReader
为提高效率加入缓冲区:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine())!=null){
if("over".equals(line))
break;
sop(line.toUpperCase());//输出大写
}
bufr.close();
(4)键盘录入数据并打印到控制台
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
(5)将键盘录入的数据存储到硬盘文件
则只需将(4)中的
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
改为:
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
即:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
(6)将硬盘文件的数据打印到控制台
则只需将(4)中的
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
改为:
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
即:
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
流操作的规律
流操作的规律:
流操作的难点:流对象很多,不知道具体用哪个
规律:
(1)第一步:先明确源和目的
源:
文本:用Reader
字节:用InputStream
目的:
文本:用Writer
字节:用OutputStream
(2)第二步:明确是不是纯文本
是:用字符流;
不是:用字节流
(3)第三步:明确流体系后,通过设备来明确具体使用哪个流对象
源设备:
键盘:System.in
硬盘:文件流File
内存:数组流ArrayStream
目的设备:
键盘:System.out
硬盘:文件流File
内存:数组流ArrayStream
File类
File类
构造方法:
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
方法摘要:
(1)创建:
boolean createNewFile()
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
boolean mkdir()
创建一级文件夹
boolean mkdirs()
创建多级文件夹
(2)判断:
boolean canExecute()
测试应用程序是否可以执行此抽象路径名表示的文件。
boolean canRead()
测试应用程序是否可以读取此抽象路径名表示的文件。
boolean canWrite()
测试应用程序是否可以修改此抽象路径名表示的文件。
int compareTo(File pathname)
按字母顺序比较两个抽象路径名。
boolean isAbsolute()
测试此抽象路径名是否为绝对路径名。
boolean isDirectory()
测试此抽象路径名表示的文件是否是一个目录。
boolean isFile()
测试此抽象路径名表示的文件是否是一个标准文件。
boolean isHidden()
测试此抽象路径名指定的文件是否是一个隐藏文件。
boolean exists()
测试此抽象路径名表示的文件或目录是否存在。
(3)获取:
String getParent()
返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
File getParentFile()
返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
String getName()
返回由此抽象路径名表示的文件或目录的名称。
String getPath()
将此抽象路径名转换为一个路径名字符串。
String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串。
File getAbsoluteFile()
返回此抽象路径名的绝对路径名形式。
(4)删除:
boolean delete()
删除此抽象路径名表示的文件或目录。
oid deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
(5)获取全部:(非常重要!!!)
String[] list()
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
String[] list(FilenameFilter filter)
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles()
返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
File[] listFiles(FileFilter filter)
返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
****FilenameFilter接口只有一个方法:
boolean accept(File dir, String name)
测试指定文件是否应该包含在某一文件列表中。
****FileFilter接口只有一个方法:
boolean accept(File dir, String name)
测试指定文件是否应该包含在某一文件列表中。
File常见操作
File类常见需求:
(1)文件名过滤:列出给定目录的所有.java文件
public void showFileName(File file)
{
String[] filenames = file.list(new FilenameFilter()//匿名内部类
{
public boolean accept(File dir,String name)//复写唯一方法
{
return name.endsWith(".java");//列出所有.java文件
}
});
}
(2)列出指定目录下的所有文件和文件夹(递归)
**示例1:不带层次递归:
public static void showDir(File dir)
{
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(files[i]);
}
}
**示例2:带层次递归:
public static void showDir(File dir,int level)
{
sop(getLevel(level)+C);//进来先打印层次和目录
level++;
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(getLevel(level)+files[i]);//是文件就打印层次和目录
}
}
public static String getLevel(int level)
{
sop("|--");
StringBuilder sb = new StringBuilder();
for(int i=0;i<level;i++)
{
sb.inset(0."| ")
}
return sb.toString();
}
(3)需求:删除带内容的目录:
public static void removeDir(File dir)
{
File[] files = file.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
removeDir(files[i]);//如果是文件夹则继续调用函数
else//如果是文件则删除。注意删除的时候打印删除的结果,防止误删或者重删的情况
sop(files[i].toString()+"::"+files[i].delete());
}
sop(dir+"::"+dir.delete());
}
(4)需求:将制定目录下的java文件的绝对路径存储到文本文件中。
思路:
**对指定目录进行递归
**获取递归过程中所有java文件的路径
**将这些路径存储到集合中
**将集合中的数据写入文件中
//对指定目录进行递归并将所以Java文件存储到集合中
public static void getFileName(File file,ArrayList<File> arraylist){
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if(files[i].isDirectory()&&!files[i].isHidden()){
getFileName(files[i],arraylist);
}else{
if(files[i].getName().endsWith(".java")){
arraylist.add(files[i]);
}
}
}
}
//将集合中所有数据存储到新文件中
public static void saveFileToNewDir(ArrayList<File> arraylist,File newDir){
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(newDir));
for (File file : arraylist) {
String fileAbsolutePath = file.getAbsolutePath();
bufw.write(fileAbsolutePath);
bufw.newLine();
bufw.flush();
}
} catch (Exception e) {
System.out.println("文件写入失败");
}finally{
try {
if(bufw!=null)
bufw.close();
} catch (Exception e2) {
System.out.println("文件写入流关闭失败");
}
}
8. 总结
一、步骤: 创建源 选择流 操作(读取|写出) 释放
二、流
节点流:离数据源|程序最近的流 | 处理流:装饰模式 提高性能增强功能 |
1、 字节流:可以处理一切(纯文本、音频、视频等) 1)、输入流 InputStream FileInputStream ByteArrayInputStream 操作:read(字节数组) a)、中间容器 byte[] flush=new byte[长度] b)、接收长度 int len =0; c)、循环读取 while(-1!=(len=流.read(flush))){} d)、操作:输出、拷贝 2)、输出流 OutputStream FileOutputStream ByteArrayOutputStream 操作:write(字节数组,0,长度) 输出 2、 字符流:只能处理纯文本 1)、输入流:Reader FileReader 操作:read(字符数组) a)、中间容器 char[] flush=new char[长度] b)、接收长度 int len =0; c)、循环读取 while(-1!=(len=流.read(flush))){} d)、操作:输出、拷贝 2)、输出流:Writer FileWriter 操作:write(字符数组,0,长度) 输出 | 1、 转换流:解码与编码字符集问题 1)、输入流:InputStreamReader à解码 2)、输出流:OutputStreamWriter—>编码 2、缓冲流:提高性能 1)、输入流:BufferedInputStream BufferedReader 2)、输出流:BufferedOutputStream BufferedWriter 3、处理数据+类型 1)、基本+字符串:必须存在才能读取 读取与写出顺序一致 a)、输入流:DataInputStream readXxx b)、输出流:DataOutputStream writeXxx 2)、引用类型:Serializable transient a)、反序列化:ObjectInputStream readObject b)、序列化:ObjectOutputStream writeObject 4、打印流: PrintStream 5、System.in out err setIn setOut 以下流使用新增方法不能发生多态 1、 ByteArrayOutputStream: toByteArray() 2、 BufferedReader: readLine() 3、 BufferedWriter:newLine() 4、 DataInputStream DataOutputStream 5、 ObjectInputStream ObjectOutputStream 6、 PrintStream
|
三、重点
四、操作
0、打印文件|目录
1、文件拷贝
2、关闭流方法
3、文件分割与合并(自学)