字符和字节的区别
字符是文本数据的最小单位,字节是二进制数据的最小单位,一个字符可能有多个字节。 字符可以通过不同的编码方式,比如ASCII,Unicode等来表示,字节通常以二进制形式直接表示 字符主要表示文本数据,字节用于处理二进制数据,比如文本,音频等 FileReader类(字符输入流)
FileReader 读取文件的步骤如下:
第一步:创建FileReader 对象与要读取的源文件接通
第二步:调用read ( ) 方法读取文件中的字符
第三步:调用close ( ) 方法关闭流
public class FileReaderTest1 {
public static void main ( String [ ] args) {
try (
Reader fr = new FileReader ( "io-app2\\src\\itheima01.txt" ) ;
) {
char [ ] buffer = new char [ 3 ] ;
int len;
while ( ( len = fr. read ( buffer) ) != - 1 ) {
System . out. print ( new String ( buffer, 0 , len) ) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
FileWriter类(字符输出流)
FileWriter 往文件中写字符数据的步骤如下:
第一步:创建FileWirter 对象与要读取的目标文件接通
第二步:调用write ( 字符数据/ 字符数组/ 字符串) 方法读取文件中的字符
第三步:调用close ( ) 方法关闭流
public class FileWriterTest2 {
public static void main ( String [ ] args) {
try (
Writer fw = new FileWriter ( "io-app2/src/itheima02out.txt" , true ) ;
) {
fw. write ( 'a' ) ;
fw. write ( 97 ) ;
fw. write ( "\r\n" ) ;
fw. write ( "我爱你中国abc" ) ;
fw. write ( "\r\n" ) ;
fw. write ( "我爱你中国abc" , 0 , 5 ) ;
fw. write ( "\r\n" ) ;
char [ ] buffer = { '黑' , '马' , 'a' , 'b' , 'c' } ;
fw. write ( buffer) ;
fw. write ( "\r\n" ) ;
fw. write ( buffer, 0 , 2 ) ;
fw. write ( "\r\n" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
FileWriter注意事项
FileWriter写完数据之后必须刷新或者关闭,写出去数据才能生效
比如:下面的代码只调用了写数据的方法,没有关流的方法。当你打开目标文件时,是看不到任何数据的。
Writer fw = new FileWriter ( "io-app2/src/itheima03out.txt" ) ;
fw. write ( 'a' ) ;
fw. write ( 'b' ) ;
fw. write ( 'c' ) ;
而下面的代码,加上了flush ( ) 方法之后,数据就会立即到目标文件中去。
Writer fw = new FileWriter ( "io-app2/src/itheima03out.txt" ) ;
fw. write ( 'a' ) ;
fw. write ( 'b' ) ;
fw. write ( 'c' ) ;
fw. flush ( ) ;
下面的代码,调用了close ( ) 方法,数据也会立即到文件中去。
因为close ( ) 方法在关闭流之前,会将内存中缓存的数据先刷新到文件,再关流。
Writer fw = new FileWriter ( "io-app2/src/itheima03out.txt" ) ;
fw. write ( 'a' ) ;
fw. write ( 'b' ) ;
fw. write ( 'c' ) ;
fw. close ( ) ;
缓冲流
作用:可以对原始流进行包装,提高原始流读写数据的性能。 底层提高性能原理:是因为在缓冲流的底层自己封装了一个长度为8KB(8129byte)的字节数组,但是缓冲流不能单独使用,它需要依赖于原始流。 字节缓冲流
public class BufferedInputStreamTest1 {
public static void main ( String [ ] args) {
try (
InputStream is = new FileInputStream ( "io-app2/src/itheima01.txt" ) ;
InputStream bis = new BufferedInputStream ( is) ;
OutputStream os = new FileOutputStream ( "io-app2/src/itheima01_bak.txt" ) ;
OutputStream bos = new BufferedOutputStream ( os) ;
) {
byte [ ] buffer = new byte [ 1024 ] ;
int len;
while ( ( len = bis. read ( buffer) ) != - 1 ) {
bos. write ( buffer, 0 , len) ;
}
System . out. println ( "复制完成!!" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
public class BufferedReaderTest2 {
public static void main ( String [ ] args) {
try (
Reader fr = new FileReader ( "io-app2\\src\\itheima04.txt" ) ;
BufferedReader br = new BufferedReader ( fr) ;
) {
String line;
while ( ( line = br. readLine ( ) ) != null ) {
System . out. println ( line) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
public class BufferedWriterTest3 {
public static void main ( String [ ] args) {
try (
Writer fw = new FileWriter ( "io-app2/src/itheima05out.txt" , true ) ;
BufferedWriter bw = new BufferedWriter ( fw) ;
) {
bw. write ( 'a' ) ;
bw. write ( 97 ) ;
bw. write ( '磊' ) ;
bw. newLine ( ) ;
bw. write ( "我爱你中国abc" ) ;
bw. newLine ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
缓冲流性能结论:**缓冲流的性能不一定比低级流高,其实低级流自己加一个数组,性能其实是不差。**只不过缓冲流帮你加了一个相对而言大小比较合理的数组 。
转换流
public class InputStreamReaderTest2 {
public static void main ( String [ ] args) {
try (
InputStream is = new FileInputStream ( "io-app2/src/itheima06.txt" ) ;
Reader isr = new InputStreamReader ( is, "GBK" ) ;
BufferedReader br = new BufferedReader ( isr) ;
) {
String line;
while ( ( line = br. readLine ( ) ) != null ) {
System . out. println ( line) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
public class OutputStreamWriterTest3 {
public static void main ( String [ ] args) {
try (
OutputStream os = new FileOutputStream ( "io-app2/src/itheima07out.txt" ) ;
Writer osw = new OutputStreamWriter ( os, "GBK" ) ;
BufferedWriter bw = new BufferedWriter ( osw) ;
) {
bw. write ( "我是中国人abc" ) ;
bw. write ( "我爱你中国123" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
打印流
打印流和普通write的区别:
打印流能将各种数据类型转换为字符串 打印流提供了便捷的方法用于打印各种数据类型 普通的write输出:需要手动将数据转换为字节数组,并将字节数组写入输出流。这意味着你需要显式地处理数据的格式化和字节转换。
OutputStream os = System . out;
try {
byte [ ] data = "Hello, World!\n" . getBytes ( ) ;
os. write ( data) ;
data = "42\n" . getBytes ( ) ;
os. write ( data) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
public class PrintTest1 {
public static void main ( String [ ] args) {
try (
PrintWriter ps =
new PrintWriter ( new FileOutputStream ( "io-app2/src/itheima08.txt" , true ) ) ;
) {
ps. print ( 97 ) ;
ps. print ( 'a' ) ;
ps. println ( "我爱你中国abc" ) ;
ps. println ( true ) ;
ps. println ( 99.5 ) ;
ps. write ( 97 ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
为什么System . out. println ( ) 能够在控制台打印语句呢?
因为System 里面有一个静态变量叫out,out的数据类型就是PrintStream ,
它就是一个打印流,而且这个打印流的默认输出目的地是控制台,
所以我们调用`System . out. pirnln ( ) `就可以往控制台打印输出任意类型的数据,而且打印啥就输出啥。
而且System 还提供了一个方法,可以修改底层的打印流,
这样我们就可以重定向打印语句的输出目的地了。我们玩一下, 直接上代码。
public class PrintTest2 {
public static void main ( String [ ] args) {
System . out. println ( "老骥伏枥" ) ;
System . out. println ( "志在千里" ) ;
try ( PrintStream ps = new PrintStream ( "io-app2/src/itheima09.txt" ) ; ) {
System . setOut ( ps) ;
System . out. println ( "烈士暮年" ) ;
System . out. println ( "壮心不已" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
此时打印语句,将往文件中打印数据,而不在控制台。
数据流
作用:可以把数据和数据类型 一并写到文件中,读取的时候也可以将数据和数据类型 一并读出来。 DataOutputStream类
往文件中写整数、小数、布尔类型数据、字符串数据
public class DataOutputStreamTest1 {
public static void main ( String [ ] args) {
try (
DataOutputStream dos =
new DataOutputStream ( new FileOutputStream ( "io-app2/src/itheima10out.txt" ) ) ;
) {
dos. writeInt ( 97 ) ;
dos. writeDouble ( 99.5 ) ;
dos. writeBoolean ( true ) ;
dos. writeUTF ( "黑马程序员666!" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
读取文件中特定类型的数据(整数、小数、字符串等)
public class DataInputStreamTest2 {
public static void main ( String [ ] args) {
try (
DataInputStream dis =
new DataInputStream ( new FileInputStream ( "io-app2/src/itheima10out.txt" ) ) ;
) {
int i = dis. readInt ( ) ;
System . out. println ( i) ;
double d = dis. readDouble ( ) ;
System . out. println ( d) ;
boolean b = dis. readBoolean ( ) ;
System . out. println ( b) ;
String rs = dis. readUTF ( ) ;
System . out. println ( rs) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
序列化流
序列化:意思就是把对象写到文件或者网络中去。(简单记:写对象) 反序列化:意思就是把对象从文件或者网络中读取出来。(简单记:读对象) 对象流是以对象为单位来读写数据。也就是把对象当做一个整体,可以写一个对象到文件,也可以从文件中把对象读取出来。 ObjectOutputStream
第一步:先准备一个User 类,必须让其实现Serializable 接口。
public class User implements Serializable {
private String loginName;
private String userName;
private int age;
private transient String passWord;
public User ( ) {
}
public User ( String loginName, String userName, int age, String passWord) {
this . loginName = loginName;
this . userName = userName;
this . age = age;
this . passWord = passWord;
}
@Override
public String toString ( ) {
return "User{" +
"loginName='" + loginName + '\'' +
", userName='" + userName + '\'' +
", age=" + age +
", passWord='" + passWord + '\'' +
'}' ;
}
}
第二步:再创建ObjectOutputStream 流对象,调用writeObject方法对象到文件。
public class Test1ObjectOutputStream {
public static void main ( String [ ] args) {
try (
ObjectOutputStream oos =
new ObjectOutputStream ( new FileOutputStream ( "io-app2/src/itheima11out.txt" ) ) ;
) {
User u = new User ( "admin" , "张三" , 32 , "666888xyz" ) ;
oos. writeObject ( u) ;
System . out. println ( "序列化对象成功!!" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}
public class Test2ObjectInputStream {
public static void main ( String [ ] args) {
try (
ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( "io-app2/src/itheima11out.txt" ) ) ;
) {
User u = ( User ) ois. readObject ( ) ;
System . out. println ( u) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
}