首页 / JAVA / Java IO流学习
Java IO流学习
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java IO流学习,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含16425字,纯文字阅读大概需要24分钟。
内容图文
![Java IO流学习](/upload/InfoBanner/zyjiaocheng/744/2ce85b47e3844783981d6e845250e80d.jpg)
Java IO流学习
??
1 IO流概述
??1、流是有起点和终止的字节序列
??2、流的分类:
??输入流/输出流
??是以当前程序为参照, 如果程序从外面读取数据就是输入流, 如果程序把数据保存到外面就是输出流
??字节流/字符流
??如果以字节为单位处理流中的数据就是字节流, 如果是以字符为单位处理流中的数据就是字符流
??节点流/处理流
直接从设备上读写数据就是节点流, 处理流是对节点流的包装
??IO流在Java.io包中 , 主要整理几个读写文件相关的流类, 在这些流类中, 如果以Stream单词结尾就是字节流, 以Reader单词结尾就是字符输入流, 以Writer结尾就是字符输出流
2 字节流
2.1 以字节为单位读取文件内容
/**
* FileInputStream类以字节为单位读取文件内容
*/
public class Test01 {
public static void main(String[] args) throws IOException {
//1)在当前程序与操作的文件之间建立流通道
//通过FileInputStream构造方法的参数指定要操作的文件
FileInputStream fis = new FileInputStream("d:/abc.txt");
//当前文件内容:abc
//2)读取文件内容, read()可以从文件中读取一个字节, 并把读取到的字节返回, 讲到文件末尾返回-1
int cc = fis.read(); //读取a, 返回97
System.out.println( cc );
cc = fis.read(); //读取b, 返回98
System.out.println(cc);
cc = fis.read(); //读取c, 返回99
System.out.println(cc);
cc = fis.read(); //讲到文件末尾, -1
System.out.println(cc);
//3) 关闭流通道
fis.close();
}
}
2.2 循环读取
/**
* FileInputStream类以字节为单位循环读取文件内容
*/
public class Test02 {
public static void main(String[] args) throws IOException {
//1)在当前程序与操作的文件之间建立流通道
//通过FileInputStream构造方法的参数指定要操作的文件
FileInputStream fis = new FileInputStream("d:/abc.txt");
//2)读取文件内容, read()可以从文件中读取一个字节, 并把读取到的字节返回, 讲到文件末尾返回-1
int cc = fis.read();
//当cc不是-1时, 说明没有到文件末尾, 可以对讲到的字节cc进行处理, 继续读取
while( cc != -1 ){
//把读到的字节cc转换为字符打印到屏幕上, 因为当前文件中只有英文字符,一个英文字符占1字节
System.out.print( (char)cc );
//继续读取,把读到的字节保存到cc中
cc = fis.read();
}
//3) 关闭流通道
fis.close();
}
}
abc
Process finished with exit code 0
2.3 以字节数组为单位读取文件内容
/**
* 从文件中读取字节保存到字节数组中
*
*/
public class Test03 {
public static void main(String[] args) throws IOException {
//1)建立流通道
FileInputStream fis = new FileInputStream("d:/abc.txt");
//文件内容:abcdefabcdef
byte [] bytes = new byte[8]; //定义长度为8的字节数组,
//2)读取文件内容,保存到字节数组中, 返回读到的字节数,如果读到文件末尾返回-1
int len = fis.read(bytes); //从文件中读取字节保存到bytes数组中, len返回值是读到的字节数组
System.out.println( len ); //8, 从文件中读取了abcdefab这8个字节
System.out.println( Arrays.toString(bytes));
//[97, 98, 99, 100, 101, 102, 97, 98]
//把读到的字节数组转换为字符串打印
System.out.println( new String(bytes , 0 ,len ) );
len = fis.read(bytes); //读取文件中cdef这4个字节
System.out.println( len ); //4
System.out.println( Arrays.toString(bytes) );
//[99, 100, 101, 102, 101, 102, 97, 98]
//把读到的4个字节转换为字符串打印
System.out.println( new String(bytes , 0 , len) );
}
}
8
[97, 98, 99, 100, 101, 102, 97, 98]
abcdefab
4
[99, 100, 101, 102, 101, 102, 97, 98]
cdef
Process finished with exit code 0
2.4 循环读取字节数组
/**
* 从文件中循环读取读取字节保存到字节数组中
*/
public class Test04 {
public static void main(String[] args) throws IOException {
//1)建立流通道
FileInputStream fis = new FileInputStream("d:/abc.txt");
byte [] bytes = new byte[8]; //定义长度为8的字节数组,
//2)读取文件内容,保存到字节数组中, 返回读到的字节数,如果读到文件末尾返回-1
int len = fis.read(bytes); //从文件中读取字节保存到bytes数组中, len返回值是读到的字节数组
//当len != -1,没有到文件末尾, 把读到的字节进行处理, 继续向下读
while( len != -1 ){
//把读到的len个字节转换为字符串打印
System.out.print( new String(bytes , 0 ,len ) );
//继续向下读, 把读到的字节存储到字节数组中
len = fis.read(bytes);
}
//3)关闭流
fis.close();
}
}
abcdefabcdef
Process finished with exit code 0
2.5 IO流的异常处理
/**
* FileInputStream读取文件中的异常处理
*
*/
public class Test05 {
public static void main(String[] args) {
// m1(); //按字节读取, 异常处理, 手动关闭流
m2(); //一次读取一个字节数组, 异常处理, 自动关闭流
}
private static void m2() {
//从JDK7开始, try资源块可以自动关闭
try ( //try资源块, 在try资源块中建立的流通道会自动关闭
FileInputStream fis = new FileInputStream("d:/abc.txt");
) {
byte[] bytes = new byte[1024] ; //字节数组的长度一般定义为1024的偶数倍
int len = fis.read(bytes);
while( len != -1 ){
System.out.print( new String(bytes,0,len));
len = fis.read(bytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void m1() {
FileInputStream fis = null;
try {
fis = new FileInputStream("d:/abc.txt");
int cc = fis.read();
while( cc != -1) {
System.out.print( (char)cc );
cc = fis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if ( fis != null ) {
try {
fis.close(); //关闭流, 相当释放系统资源,
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.6 向文件中写入内容
/**
* FileOutputStream把数据以字节为单位保存到文件中
*/
public class Test06 {
public static void main(String[] args) throws IOException {
//1)建立与文件的流通道
//如果文件不存在,系统会创建一个新的文件, 如果文件已存在,会覆盖文件原来的内容
// FileOutputStream fos = new FileOutputStream("d:/def.txt"); //以覆盖的方式打开 文件
//如果文件 不存在就创建文件, 如果文件已存在, 把新写入的内容追加到文件末尾
FileOutputStream fos = new FileOutputStream("d:/def.txt" , true ); //以追加的方式
//2)把数组以字节为单位保存到文件中
fos.write( 97 ); //一次写一个字节
fos.write(98);
fos.write(99);
//一次写一个字节数组
byte[] bytes = "hello,abcdefg".getBytes();
fos.write(bytes);
//把字节数组的部分字节保存到文件中
fos.write(bytes, 0, 5); //把bytes字节数组中从0开始的5个字节保存到文件中
//3)关闭流通道
fos.close();
}
}
2.7 实现文件的复制
/**
* 以字节为单位实现文件复制
*
*/
public class Test07 {
public static void main(String[] args) {
String file1 = "F:\\code\\test\\src\\main\\java\\io\\fileinputstream\\Test07.java" ;
String dest1 = "F:\\test.java";
copyfile(file1, dest1);
copyfile2(file1, file1);
}
//文件复制,一 次复制一个数组
public static void copyfile2( String srcFile, String destFile) {
try(
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
) {
byte [] bytes = new byte[1024];
int len = fis.read(bytes);
while( len != -1 ){
fos.write(bytes, 0, len);
len = fis.read(bytes);
}
} catch (Exception e) {
}
}
//定义方法,实现文件的复制, 把srcfile文件的内容复制到destFile文件中, 一次复制一个字节
public static void copyfile( String srcFile, String destFile) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
int cc = fis.read(); //从输入流中读取一个字节
//当读到的字节不是-1, 就把读到的字节cc保存到输出流中
while( cc != -1 ){
fos.write(cc);
cc = fis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if ( fis != null ) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3 字符流
??FileReader是以字符为单位读取文件中的内容
??FileWriter是以字符为单位把数据保存到文件中
??注意:
??1)FileReader/FileWriter只能读写纯文本文件
??2)FileReader/FileWrite读写的文本文件编码要与当前环境编码兼容
3.1 读取文件内容
/**
* FileReader读取文件内容
*/
public class Test01 {
public static void main(String[] args) throws IOException {
//1)建立流通道
FileReader fr = new FileReader("f:/test.java"); //test07.java文件的编码是utf-8
// FileReader fr = new FileReader("d:/abc.txt"); //abc.java文件编码是GBK
//2)读取内容 , read()一次读取一个字符, 返回字符的码值, 读到文件末尾返回-1
int cc = fr.read();
while( cc != -1){
System.out.print( (char)cc );
cc = fr.read();
}
//3)关闭流
fr.close();
}
}
3.2 读取字符数组
/**
* 一次读取一个字符数组
*/
public class Test02 {
public static void main(String[] args) {
try (
//在try资源块中建立流通道, 会自动关闭
FileReader fr = new FileReader("d:/test07.java");
){
//创建字符数组
char [] contents = new char[1024];
//从文件中读取字符保存到字符数组中, 返回读到的字符个数, 读到文件末尾返回-1
int len = fr.read(contents);
while( len != -1 ){
//把读到的字符转换为字符串
System.out.print( new String(contents, 0, len ) );
len = fr.read(contents);
}
} catch (Exception e) {
}
}
}
3.3 向文件中写入字符
/**
* FileWriter
*
*/
public class Test03 {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("d:/def.txt"); //以覆盖的方式打开
//一次写一个字符
fw.write(97); //字符的码值
fw.write(30028);
fw.write('汉');
//一次写一个字符数组
char [] contents = "你好你好".toCharArray();
fw.write(contents);
//一次写一个字符串
fw.write("一次写一个字符串");
//换行, 在中文Windows系统中,换行需要两个字符\r\n
fw.write("\r\n");
//一次写字符数组的部分字符
fw.write(contents, 0 , 4);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.4 实现文本的复制
4 转换流
??1) 文本文件编码与当前环境编码兼容时,使用FileReader/FielWriter读写,
??2) 当文本文件编码与当前环境编码 不 兼容时, 使用InputStreamReader/OutputStreamWriter
??3)这两个流类称为转换流类
??4)InputStreamReader可以把字节流转换为字符流
??5)OutputStreamWriter可以把字符流转换为字节流
public class Test04 {
public static void main(String[] args) throws IOException {
// m1() ; //以指定的编码格式读取文本文件
m2(); //以指定的编码把数据保存到文件中
}
private static void m2() throws IOException {
//向d:/abc.txt文件中保存数据, 该文件是以GBK编码
OutputStream out = new FileOutputStream("d:/abc.txt", true);
//以指定的编码把字符转换为字节流
OutputStreamWriter osw = new OutputStreamWriter(out, "GBK");
osw.write("当前环境使用UTF8编码, 把数据保存到GBK文件中");
osw.close();
}
private static void m1() throws IOException {
//d:/Abc.txt文件是GBK编码,
//InputStream是一个抽象类, 需要赋值子类对象, FileInputStream继承了InputStream
// InputStream in = new FileInputStream("d:/abc.txt");
FileInputStream in = new FileInputStream("d:/abc.txt");
//以GBK的编码读取in字节流中的数据,
InputStreamReader isr = new InputStreamReader(in, "GBK");
int cc = isr.read();
while( cc!=-1){
System.out.print((char)cc);
cc = isr.read();
}
isr.close();
}
}
5 缓冲流
/**
* BufferedReader/BufferedWriter
* 缓冲字符流
*/
public class Test05 {
public static void main(String[] args) throws IOException {
// m1(); //使用BufferedReader读取文件
m2(); //使用BufferedWriter保存数据到文件中
}
private static void m2() throws IOException {
//建立字符流通道
FileWriter out = new FileWriter("d:/def.txt", true );
//对字符流进行缓冲
BufferedWriter bw = new BufferedWriter(out);
//使用缓冲流时,是把数组保存到缓冲区中 , 并没有立即保存到文件中
bw.write("这是使用字符缓冲流写入的数据");
// bw.flush(); //会把缓冲区的数据清空到文件中
bw.close();
}
private static void m1() throws IOException {
//建立字符流通道
Reader in = new FileReader("d:/test07.java");
//对字符流进行缓冲
BufferedReader br = new BufferedReader(in);
//可以从字符流中一次读取一行, 读到文件末尾返回null
String line = br.readLine();
while( line != null ){
System.out.println( line );
line = br.readLine();
}
br.close();
}
}
6 对象序列化
??序列化
????把一个对象转换为01二进制序列
??对象反序列化:
????把一组01二进制转换为对象
??ObjectOutputStream类可以把对象序列化到文件中,简单的 理解为把对象保存到文件中
??ObjectInputStream可以进行对象的反序列化, 简单的理解为从文件中把对象读出来
??注意:
??1)对象序列化/反序列化的前提是, 对象的类要实现Serializable接口
??2)如果某个类的对象要进行序列化, 一般情况下,在会在类中手动的添加一个序列化版本号字段
public class Person implements Serializable {
String name;
int age;
String gender;
//手动的添加一个serialVersionUID字段, 防止在反序列化时产生版本号不一致的异常
private static final long serialVersionUID = -713246547316498710L;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
}
/**
* 对象序列化
* 使用ObjectOutputStream类
* 前提是类要实现Serializable接口
*
*/
public class Test01 {
public static void main(String[] args) throws IOException {
//1) 创建Person对象
Person p1 = new Person("lisi", 18);
//2) 把p1保存到文件中
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("d:/obj.txt") );
oos.writeObject(p1);
oos.close();
}
}
/**
* 对象反序列化
* 使用ObjectInputStream
*/
public class Test02 {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream( new FileInputStream("d:/obj.txt"));
Object obj = ois.readObject();
//readObject()是从文件中读取了一个Person对象, 使用Object类型的引用obj来保存该对象的引用
ois.close();
System.out.println( obj ); //调用Perosn对象的toString()
/*场景描述:
* 当把Person类对象保存到文件以后
* 在Person类中添加了一个字段,修改了Person类的结构
* 再进行反序列化时, 产生 了以下异常
* java.io.InvalidClassException: com.bjpowernode.chapter06.objectinputstream.Person;
* local class incompatible: stream classdesc serialVersionUID = -1846058886603673947,
* local class serialVersionUID = -7054941406793751712
* 该异常是说, 流中serialVersionUID字段的值与当前字节码文件中serialVersionUID字段的值不相等, 产生的异常
* 反序列化时, 使用流中serialVersionUID字段的值与字节码文件中该字段的值不相等
*
*解决思路:
* 保证反序列化时,流中serialVersionUID字段的值与字节码文件中 serialVersionUID字段的值相等即可
*办法:
* 在类实现了Serializable接口后, 一般会手动的添加一个serialVersionUID字段
*/
}
}
7 打印流
/**
* PrintStream
*/
public class Test {
public static void main(String[] args) throws IOException {
//以追加的方式建立一个字节流
OutputStream out = new FileOutputStream("d:/log.txt" ,true );
//创建打印流
PrintStream ps = new PrintStream(out);
ps.print("hehe");
ps.println("world");
//System类中out成员就是 PrintStream流, System.out代表系统的标准输出设备,即显示器
System.out.println("默认在显示器上打印信息");
//修改System.out的输出方向
System.setOut( ps );
System.out.println("这一行数据,就不显示在屏幕上, 输出到ps打印流中,即 log.txt文件");
//有时, 会把异常信息打印到日志文件中
try {
FileInputStream fis = new FileInputStream("g:/hehe.txt");
} catch (Exception e) {
// e.printStackTrace(); //在屏幕上打印
e.printStackTrace(ps); //打印以ps流中
}
}
}
8 File类
/**
* 使用File获得文件的属性
*
*/
public class Test01 {
public static void main(String[] args) throws IOException {
//创建File对象, 通过绝对路径指定一个文件
File f1 = new File("D:\\abc.txt");
//如果是相对路径, 是相对于当前项目的目录
// File f1 = new File("hehe.txt");
//创建文件
f1.createNewFile();
//返回文件的相关属性
System.out.println( f1.length() ); //文件大小
long millis = f1.lastModified(); //最后一个修改时间, 是一个毫秒数
Date date = new Date(millis);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println( sdf.format(date) );
System.out.println( f1.getAbsolutePath()); //绝对路径
System.out.println( f1.getParent()); //上一级文件夹
System.out.println( f1.getName()); //对象名
System.out.println( f1.exists()); //是否存在
System.out.println( f1.isAbsolute()); //是否绝对路径
System.out.println( f1.isDirectory() ); //是否目录
System.out.println( f1.isFile() ); //是否文件
}
}
12
2019-07-28 15:57:56
D:\abc.txt
D:\
abc.txt
true
true
false
true
Process finished with exit code 0
/**
* File对文件夹操作
*
*/
public class Test02 {
public static void main(String[] args) {
// File f = new File("d:/java");
//// f.mkdir(); //创建文件夹, 如果上一级目录不存在,创建不成功
// f.mkdirs(); //创建文件夹, 如果上一级目录不存在,先创建上一组目录再创建当前文件夹
listSubs("d:/java"); //显示指定文件夹的内容
}
//显示指定目录的内容
private static void listSubs1(String foldername) {
File dir = new File(foldername);
String[] list = dir.list();
for (String string : list) {
System.out.println( string );
}
}
//显示指定目录的内容, 显示完整路径
private static void listSubs2(String foldername) {
File dir = new File(foldername);
File[] listFiles = dir.listFiles();
for (File file : listFiles) {
System.out.println( file.getAbsolutePath() );
}
}
//显示指定目录的内容, 显示完整路径, 包括子文件夹的内容
private static void listSubs(String foldername) {
File dir = new File(foldername);
File[] listFiles = dir.listFiles();
for (File file : listFiles) {
System.out.println( file.getAbsolutePath() );
//如果file成员是文件夹, 则显示该子文件内容
if ( file.isDirectory() ) {
listSubs(file.getAbsolutePath()); //递归调用
}
}
}
}
内容总结
以上是互联网集市为您收集整理的Java IO流学习全部内容,希望文章能够帮你解决Java IO流学习所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。