IO流学习笔记
1.File类
文件和目录路径名的抽象表示形式。
4种构造方法
File(File parent, String child)
File(File parent, String child)
File(String parent, String child)
创建一个文件
案例【1】
import java.io.File;
import java.io.IOException; public class FileDemo { /**
* 创建一个文件
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
File f = new File("F:\\file.txt");
System.out.println(f.exists());
try {
f.createNewFile();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println(f.exists());
} }
运行结果:
false
true
打开F盘会发现存在一个0字节的file.txt文件
路径分隔符
在不同的系统中路径分隔符是不同的,所以想要代码有更好的移植性,我们采用pathSeparator
和separator
公共静态字段。
案例【2】
import java.io.File;
import java.io.IOException; public class FileDemo { /**
* 创建一个文件
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
String filename ="F:"+File.separator+"file.text2";
File f = new File(filename);
File f2 = new File("1.txt"); try {
f.createNewFile();
f2.createNewFile();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println(f.getName());
System.out.println(f.getAbsolutePath());
System.out.println(f.getPath());
System.out.println(f2.getName());
System.out.println(f2.getAbsolutePath());
System.out.println(f2.getPath());
} }
输出结果:
file.text2
F:\file.text2
F:\file.text2
1.txt
F:\ec\HelloWorld\1.txt
1.txt
注意体会AbsolutePath和Path(我的项目写在F:\ec\HelloWorld文件夹中)
创建多级文件夹
File类中的mkdir()和mkdirs()可以用来创建目录,区别是mkdirs()可以创建多层目录,即同时创建这个目录的父目录和父目录的目录,而mkdir()
要求创建目录的父目录已经存在。
案例【3】
import java.io.File; public class FileDemo { /**
* 创建一个多级文件夹
*/
public static void main(String[] args) {
String filename ="F:"+File.separator+"a"+File.separator+"b";
File f = new File(filename);
f.mkdirs(); } }
运行完打开F盘发现多了文件夹a,打开文件夹a。里面有空文件夹b。
列出指定目录的全部文件(不包括子目录)
File类中存在list和Filelist方法,返回的分别是String类型的数组和File类型的数组
案例【4】
import java.io.File; public class FileDemo { /**
* 列出指定目录文件(不包括子目录)
*/
public static void main(String[] args) {
String filename ="F:"+File.separator+"src";
File f = new File(filename);
File[] f2 = f.listFiles();
for(int i=0;i<f2.length;i++)
{
System.out.println(f2[i]);
}
} }
输出:
F:\src\A.class
F:\src\abc.java
F:\src\B$1.class
F:\src\B$C.class
F:\src\B.class
F:\src\back
F:\src\Car.class
F:\src\day01.class
F:\src\pack
列出指定目录的全部文件(包括子目录)
对于这个问题,我们需要用到isDirectory()方法和递归。
对于isDirectory()方法,当且仅当此抽象路径名表示的文件存在且是一个目录时,返回 true
;否则返回 false
。
因此我们可以对文件夹列出使用递归,如果文件夹下还有文件夹,则对后者接着使用列出方法。
案例【5】
import java.io.File; public class FileDemo { /**
* 列出指定目录文件(包括子目录)
*/
public static void main(String[] args) {
String filename ="F:"+File.separator+"src";
File f = new File(filename);
listAll(f);
} public static void listAll(File f)
{
File[] f2 =f.listFiles();
for(int i=0;i<f2.length;i++)
{
if(f2[i].isDirectory())
{
System.out.println(f2[i]);
listAll(f2[i]);
}
else
{
System.out.println(f2[i]);
}
}
}
}
输出结果:
F:\src\A.class
F:\src\abc.java
F:\src\B$1.class
F:\src\B$C.class
F:\src\B.class
F:\src\back
F:\src\back\packageDemo.class
F:\src\Car.class
F:\src\day01.class
F:\src\pack
F:\src\pack\abc.class
我们可以发现虽然列出了所有的文件夹和文件夹下的文件,但是我们直观上并不好看出哪些是一级目录下的,哪些是子目录下的文件,
所以我们对此进行改进。
案例【6】
import java.io.File; public class FileDemo { /**
* 列出指定目录文件(包括子目录)
*/
public static int level =0;
public static void main(String[] args) {
String filename ="F:"+File.separator+"src";
File f = new File(filename);
listAll(f);
} public static void listAll(File f)
{
File[] f2 =f.listFiles();
for(int i=0;i<f2.length;i++)
{
if(f2[i].isDirectory())
{
print(level);
System.out.println(f2[i]);
level++;
listAll(f2[i]);
}
else
{
print(level);
System.out.println(f2[i]);
}
}
level--;
} private static void print(int level) {
for(int i=0;i<level;i++)
System.out.print("——");
}
}
输出:
F:\src\A.class
F:\src\B$1.class
F:\src\B$C.class
F:\src\B.class
F:\src\back
+F:\src\back\abc.java
+F:\src\back\packageDemo.class
F:\src\Car.class
F:\src\day01.class
F:\src\pack
+F:\src\pack\abc.class
我们可以清楚的看到一级目录下的文件和文件夹是没有+号的,二级目录有个+号,如果有三级目录的话,会出现两个+号。
文件过滤
当我们需要在一堆文件中找到我们需要的特定类型文件时我们可以根据后缀名过滤。
public String[] list(FilenameFilter filter)
public File[] listFiles(FilenameFilter filter)
这两个方法需要FilenameFilter对象参数。
FilenameFilter是一个接口,其中声明了一个方法
boolean accept(File dir ,String name)
我在F盘src文件夹中添加了2个txt文本文件,并将其过滤去。
案例【7】
import java.io.*; //后缀名文件过滤器
public class SuffixFilter implements FilenameFilter { public boolean accept(File dir, String name) { return name.endsWith(".txt");
} } import java.io.File; public class FileDemo { /**
* 列出指定目录文件(不包括子目录)下的txt格式文件
*/
public static void main(String[] args) {
String filename ="F:"+File.separator+"src";
File f = new File(filename);
File[] f2 = f.listFiles(new SuffixFilter());
for(int i=;i<f2.length;i++)
{
System.out.println(f2[i]);
}
} }
运行结果:
F:\src\新建文本文档 (2).txt
F:\src\新建文本文档.txt
我们可以看到成功筛选出txt文档文件。
2字符流
Reader和Writer是字符流的超类,直接继承自Object类的抽象类。
以字符为单位进行读写。
这些体系的子类都以父类名作为后缀。
而且子类名的前缀就是该对象的功能。
以子类FileReader和FileWriter为例作为说明
案例【8】
import java.io.*; public class FileDemo { /**
* 字符流读写
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"字符流.txt"; FileWriter fw =new FileWriter(filename);
fw.write("zerocoin你好");
fw.close();
FileReader fr =new FileReader(filename);
System.out.println((char)fr.read());
int ch=;
while((ch=fr.read())!=-)
{
System.out.print((char)ch);
}
fr.close(); }
输出结果:
z
erocoin你好
F盘中出现字符流.txt,内容是zerocoin你好。
不难发现read()方法返回的是int型,当所有数据读完时,返回—1。
read方法中也可以添加参数。
案例【9】
import java.io.*; public class FileDemo { /**
* 字符流读写
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"字符流.txt"; FileWriter fw =new FileWriter(filename);
fw.write("zerocoin你好");
fw.close();
FileReader fr =new FileReader(filename);
//System.out.println((char)fr.read());
char[] ch=new char[1024];
int len=0;
while((len=fr.read(ch))!=-1)//数组作为参数,读取到数组中
{
System.out.print(new String(ch,0,len));
}
fr.close(); } }
zerocoin你好
我们在往已存在内容的文件中用Write方法的话,会从头开始写,文件内容会被覆盖,
我们可以使用FileWriter另一个构造器生成对象进行续写。
即FileWriter(String fileName, true)。
3字节流
字节流按字节读写
案例【9】
import java.io.*; public class FileDemo { /**
* 字节流读写
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"字节流.txt";
FileOutputStream fo =new FileOutputStream(filename);
FileInputStream fi = new FileInputStream(filename);
//fo.write("zerocoin你好");错误,字节流没有write(string s)方法
fo.write("zerocoin你好".getBytes());
fo.close();
byte [] ch=new byte[1024];
int len=0;
while((len=fi.read(ch))!=-1)//数组作为参数,读取到数组中
{
System.out.print(new String(ch,0,len));
}
fi.close(); } }
输出
zerocoin你好
F盘中出现字节流.txt
关于字节流和字符流的区别(参考于Rollen博客)
实际上字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的,但是字符流在操作的 时候下后是会用到缓冲区的,是通过缓冲区来操作文件的。
读者可以试着将上面的字节流和字符流的程序的最后一行关闭文件的代码注释掉,然后运行程序看看。你就会发现使用字节流的话,文件中已经存在内容,但是使用字符流的时候,文件中还是没有内容的,这个时候就要刷新缓冲区。
使用字节流好还是字符流好呢?
答案是字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
4. BufferedReader和BufferedWriter流
从字符输入流中读写文本,缓冲各个字符,从而实现字符、数组和行的高效读写。
存在newLine()
,readLine(),reset(),skip()等新方法
案例【10】
import java.io.*; public class FileDemo { /**
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"字符流.txt"; FileWriter fw =new FileWriter(filename);
BufferedWriter bfw = new BufferedWriter(fw);
bfw.write("第一行");
bfw.newLine();//分行符
bfw.write("012345", 0, 3);//从0读到2位
bfw.close();
FileReader fr =new FileReader(filename);
BufferedReader bfr =new BufferedReader(fr); String str=null;
//readLine()返回String类型,读完返回null
while((str=bfr.readLine())!=null)
{
System.out.println(str);
}
bfr.close(); } }
输出结果:
第一行
012
F盘中字符流.txt也被写入这输出。
BufferedInputStream和BufferOutputStream类似。
缓冲区中无非就是封装了一个数组,
并对外提供了更多的方法对数组进行访问。
其实这些方法最终操作的都是数组的角标。
缓冲的原理:
其实就是从源中获取一批数据装进缓冲区中。
在从缓冲区中不断的取出一个一个数据。
好处:效率更高。
5转换流
InputStreamReader和OutputStreamWriter 字节流转字符流
转换流的出现方便了对文件的读写,她在字符流与字节流之间架起了一座桥梁,使原本毫无关联的两种流操作能够进行转化,提高了程序的灵活性
import java.io.*; public class FileDemo { public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"转换流.txt";
File f =new File(filename);
FileOutputStream out =new FileOutputStream(f);
OutputStreamWriter osw =new OutputStreamWriter(out);
BufferedWriter bufw = new BufferedWriter(osw);
bufw.write("hello zerocoin");
bufw.close(); } }
F盘下出现了转换流.txt.
InputStreamReader也是同样的用法。
下面主要讲下InputStreamReader(InputStream in,String charsetName)
和 OutputStreamWriter(OutputStream out,String charsetName)两种构造器。
import java.io.*; public class FileDemo {
/**
* 用UTF编码写,默认编码GBK读
*/ public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"转换流.txt";
File f =new File(filename);
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream(f),"UTF-8");
osw.write("hello你好吗zerocoin");
osw.close();
InputStreamReader isr=new InputStreamReader(new FileInputStream(f));
char []ch = new char[1024];
int len;
while((len=isr.read(ch))!=-1)
{
System.out.println(new String(ch,0,len));
} }
}
结果:hello浣犲ソ鍚梲erocoin
为什么会出现乱码呢?因为当我们InputStreamReader(InputStream in)和OutputStreamWriter(OutputStream out)的默认
都是用的系统的字符集GBK。所以当我们用UTF—8码进行写入,GBK进行读取时就会出现乱码。我们可以设置用UTF—8码读,这样
就可以解决问题。
import java.io.*; public class FileDemo {
/**
* 用UTF-8编码写,UTF-8读
*/ public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"转换流.txt";
File f =new File(filename);
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream(f),"UTF-8");
osw.write("hello你好吗zerocoin");
osw.close();
InputStreamReader isr=new InputStreamReader(new FileInputStream(f),"UTF-8");
char []ch = new char[1024];
int len;
while((len=isr.read(ch))!=-1)
{
System.out.println(new String(ch,0,len));
} }
}
输出:hello你好吗zerocoin
6.标准流
JAVA语言包中有一个类System,这个类没有共有的构建器,因此我们并不能创建这个类的实例对象。
它提供了三个静态类字段。
public final static InputStream in;
public final static PrintStream out;
public final static PrintStream err;
import java.io.*; public class FileDemo {
/**
* 控制台写入文件
*/ public static void main(String[] args) throws IOException {
String filename ="F:"+File.separator+"text.txt";
File f =new File(filename);
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new
FileOutputStream(f)));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
} }
}
输入:
你好
zerocoin
over
当输入over时,程序结束。text中写入
你好
zerocoin
7 Properties集合
* Map
* |--Hashtable
* |--Properties
* 特点:
* 1,该集合中的键和值都是字符串类型。
* 2,集合中的数据可以保存到流中,或者从流获取。
* 通常该集合用于操作以键值对形式存在的配置文件。
Properties
类表示了一个持久的属性集。Properties
可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
import java.io.FileOutputStream;
import java.util.Properties; public class PropertiesDemo{
public static void main(String[] args) throws Exception {
propertiesDemo();
} public static void propertiesDemo() throws Exception {
Properties prop = new Properties(); prop.setProperty( "zhangsan","10" );
prop.setProperty( "lisi","20" );
prop.setProperty( "wangwu","30" );
prop.setProperty( "zhaoliu","40" ); //想要将这些集合中的字符串键值信息持久化存储到文件中
//需要关联输出流
FileOutputStream fos = new FileOutputStream("info.txt" ); //将集合中数据存储到文件中
prop.store(fos, "name+age"); fos.close();
}
}
IO流学习笔记的更多相关文章
- JAVA.IO流学习笔记
一.java.io 的描述 通过数据流.序列化和文件系统提供系统输入和输出.IO流用来处理设备之间的数据传输 二.流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数 ...
- IO流学习笔记(二)之BufferedWriter与BufferedReader及实例Demo
在之前的学习笔记(http://blog.csdn.net/megustas_jjc/article/details/72853059)中,FileWriter与FileReader的Demo使用的中 ...
- IO流学习笔记(一)之FileWriter与FileReader
IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按照操作数据分为两种:字节流和字符流 流按流向分为:输入流和输出流 输入流和输出流是相对于 ...
- Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream
Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ ...
- Java IO流学习总结八:Commons IO 2.5-IOUtils
Java IO流学习总结八:Commons IO 2.5-IOUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/550519 ...
- Java IO流学习总结(1)
Java IO流学习总结 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本 ...
- Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter
在上一篇文章中Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream介绍了缓冲流中的字节流,而这一篇着重介绍缓冲流中字符流Buffered ...
- Java IO流学习总结一:输入输出流
Java IO流学习总结一:输入输出流 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54292148 本文出自[赵彦军的博客] J ...
- Java IO流学习
Java IO流学习 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是 ...
随机推荐
- 统计 MapReduce 输出路径修改。
先在上一篇MR 的104 行加入代码.jobConf.setOutputFormat(MyMultipleFilesTextOutputFormat.class); 用意是自定义 job 的输出格式: ...
- mysql---union的使用方法
union的作用非常easy用来合并两条sql的结果集 语法: SQL1 UNION SQL2 现有一张价格表 要求:求出价格低于2000和价格高于3000的商品.不能用or和not between- ...
- android动画-拖动
先上图看效果 实质上说是动画有点不妥,确切的说应该是手势的处理,废话不多说看代码 SimpleDragSample.java public class SimpleDragSample extends ...
- C#泛型链表Demo
/// <summary> /// 节点 /// </summary> /// <typeparam name="T"></typepar ...
- BZOJ 3262 cdq分治 OR 树套树
注意判断 三个条件都一样的-- (CDQ分治 其实并不是很难理解 只是想不到--) CDQ分治: //By SiriusRen #include <cstdio> #include < ...
- Sqoop 的基本架构
不多说,直接上干货! Sqoop 的基本架构图 注意: Sqoop,只需map task就可以了,因为,它只是做数据传输,不需做数据处理.
- Coderfroces 864 D. Make a Permutation!
D. Make a Permutation! Ivan has an array consisting of n elements. Each of the elements is an intege ...
- Ubuntu源配置
一.图形界面配置 新手推荐使用图形界面配置: 系统工具 -> 软件和更新-> Ubuntu软件-> 下载自:-> 其他站点 点击 选择最佳服务器(将通过连接测试确定最佳镜像) ...
- mysql的my.cnf文件详解
一.缘由 最近要接手数据库的维护工作,公司首选MySQL.对于MySQL的理解,我认为很多性能优化工作.主从主主复制都是在调整参数,来适应不同时期不同数量级的数据. 故,理解透彻my.cnf里的参数是 ...
- 数据库范式小结 1NF 2NF BCNF 3NF 4NF DB normal form
1. 1NF指关系中的每个变量不可再分 2. 2NF指消除了非主属性对码(candidate key)的部分依赖的1NF 比如(S#,C#)-> SN ,(S#,C#)-> SD .S#- ...