文件流:使用文件输入流读取文件中的数据:
public class FISDemo {public static void main(String[] args) throws IOException {//将fos.dat文件中的字节读取回来/*fos.dat文件中的数据:00000001 00000010*/FileInputStream fis = new FileInputStream("fos.dat");
java.io.InputStream(所有字节输入流的超类)定义着读取字节的相关方法
int read()
读取1个字节并以int型整数返回读取到的字节内容,返回的int值中对应的2进制的"低八位"
就是读取到的数据。如果返回的int值为整数-1(这是一个特殊值,32位2进制全都是1)表达是流读取到了末尾了。
int read(byte[] data)
文件输入流重写了上述两个方法用来从文件中读取对应的字节。
fos.dat文件中的数据:
00000001 00000010
^^^^^^^^
第一次读取的字节
当我们第一次调用:
int d = fis.read();//读取的是文件中第一个字节
该int值d对应的2进制:
00000000 00000000 00000000 00000001
|------自动补充24个0-------| ^^^^^^^^
读取到的数据
而该2进制对应的整数就是1.
int d = fis.read();//读取到的就是整数1System.out.println(d);
fos.dat文件中的数据:
00000001 00000010
^^^^^^^^
第二次读取的字节
当我们第二次调用:
d = fis.read();//读取的是文件中第二个字节
该int值d对应的2进制:
00000000 00000000 00000000 00000010
|------自动补充24个0-------| ^^^^^^^^
读取到的数据
而该2进制对应的整数就是2.
d = fis.read();//2System.out.println(d);
fos.dat文件中的数据:
00000001 00000010 文件末尾
^^^^^^^^
没有第三个字节
当我们第三次调用:
d = fis.read();//读取到文件末尾了!
该int值d对应的2进制:
11111111 11111111 11111111 11111111
该数字是正常读取1个字节永远表达不了的值。并且-1的2进制格式好记。因此用它表达读取到了末尾。
d = fis.read();//-1System.out.println(d);fis.close();
文件复制
利用文件输入流与输出流实现文件的复制操作
public class CopyDemo {public static void main(String[] args) throws IOException {//用文件输入流读取待复制的文件
// FileInputStream fis = new FileInputStream("image.jpg");FileInputStream fis = new FileInputStream("01.rmvb");//用文件输出流向复制文件中写入复制的数据
// FileOutputStream fos = new FileOutputStream("image_cp.jpg");FileOutputStream fos = new FileOutputStream("01_cp.rmvb");/*原文件image.jpg中的数据10100011 00111100 00001111 11110000....^^^^^^^^读取该字节第一次调用:int d = fis.read();d的2进制:00000000 00000000 00000000 10100011读到的字节fos向复制的文件image_cp.jpg中写入字节第一次调用:fos.write(d);作用:将给定的int值d的2进制的"低八位"写入到文件中d的2进制:00000000 00000000 00000000 10100011写出字节调用后image_cp.jpg文件数据:10100011*//*循环条件是只要文件没有读到末尾就应该复制如何直到读取到末尾了呢?前提是:要先尝试读取一个字节,如果返回值是-1就说明读到末尾了如果返回值不是-1,则说明读取到的是一个字节的内容,就要将他写入到复制文件中*/int d;//先定义一个变量,用于记录每次读取到的数据long start = System.currentTimeMillis();//获取当前系统时间while ((d = fis.read()) != -1) {fos.write(d);}long end = System.currentTimeMillis();System.out.println("复制完毕!耗时:" + (end - start) + "ms");fis.close();fos.close();}
}
块读写的文件复制操作
nt read(byte[] data) 一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中。 返回值为实际读取到的字节量。若返回值为-1则表示读取到了文件末尾。
块写操作 void write(byte[] data) 一次性将给定的字节数组所有字节写入到文件中
void write(byte[] data,int offset,int len) 一次性将给定的字节数组从下标offset处开始的连续len个字节写入文件中里面:
/*** 通过提高每次读写的数据,减少读写次数可以提高读写效率。*/
public class CopyDemo2 {public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("01.rmvb");FileOutputStream fos = new FileOutputStream("01_cp.rmvb");/*块读:一次性读取一组字节块写:一次性将写出一组字节java.io.InputStream上定义了块读字节的方法:int read(byte[] data)一次性读取给定字节数组length个字节并从头开始装入到数组中。返回值为实际读取到的字节量如果返回值为-1则表示流读取到了末尾。文件流重写了该方法,作用是块读文件里的数据。java.io.OutputStream上定义了块写字节的方法:void write(byte[] data)一次性将给定的字节数组中所有的字节写出。void write(byte[] data,int offset,int len)一次性将给定的字节数组data中从下标offset处开始的连续len个字节写出。原文件数据(假设文件共6个字节):11110000 00001111 01010101 11111111 00000000 10101010byte[] buf = new byte[4];//创建一个长度为4的字节数组buf默认的样子(每个元素若以2进制表现):{00000000,00000000,00000000,00000000}int len;//记录每次实际读取的字节数当第一次调用:len = fis.read(buf);由于字节数组buf的长度为4.因此可以一次性最多从文件中读取4个字节并装入到buf数组中返回值len表示的整数是这次实际读取到了几个字节。原文件数据(假设文件共6个字节):11110000 00001111 01010101 11111111 00000000 10101010^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^第一次读取的4个字节buf:{11110000,00001111,01010101,11111111}len:4 表示本次读取到了4个字节第二次调用:len = fis.read(buf);原文件数据(假设文件共6个字节):11110000 00001111 01010101 11111111 00000000 10101010 文件末尾了^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^本次实际只能读取到2个字节buf:{00000000,10101010,01010101,11111111}|本次新读的2字节数据| |---上次的旧数据---|len:2表示本次实际只读取到了2个字节。它的意义就是告诉你buf数组中前几个字节是本次真实读取到的数据第三次调用:len = fis.read(buf);原文件数据(假设文件共6个字节):11110000 00001111 01010101 11111111 00000000 10101010 文件末尾了^^^^^^^^ ^^^^^^^^ ^^^^^^^^ ^^^^^^^^buf:{00000000,10101010,01010101,11111111} 没有任何变化!len:-1 表示本次读取时已经是文件末尾了!!*//*00000000 8位2进制 1byte 1字节1024byte = 1kb1024kb = 1mb1024mb = 1gb1024gb = 1tb*//*编译完该句代码:byte[] buf = new byte[10240];在实际开发中,有时候用一个计算表达式更能表现这个值的含义时,我们不妨使用计算表达式long t = 864000000;long t = 60 * 60 * 24 * 1000;*/byte[] buf = new byte[1024 * 10];//10kbint len;//记录每次实际读取到的字节数long start = System.currentTimeMillis();while ((len = fis.read(buf)) != -1) {fos.write(buf, 0, len);}long end = System.currentTimeMillis();System.out.println("复制完毕,耗时:" + (end - start) + "ms");fis.close();fos.close();}
}
写文本数据
String提供方法: byte[] getBytes(String charsetName) 将当前字符串转换为一组字节
参数为字符集的名字,常
/*** 使用文件输出流向文件中写入文本数据*/
public class WriteStringDemo {public static void main(String[] args) throws IOException {/*1:创建一个文件输出流2:将写出的文字先转换为2进制(一组字节)3:关闭流文件流有两种创建方式:1:覆盖模式,对应的构造器:FileOutputStream(String filename)FileOutputStream(File file)所谓覆盖模式:文件流在创建是若发现该文件已存在,则会将该文件原内容全部删除。然后在陆续将通过该流写出的内容保存到文件中。 */FileOutputStream fos = new FileOutputStream("fos.txt",true);String line = "让我再看你一遍,从南到北。";/*String提供了将内容转换为一组字节的方法:getBytes()java.nio.charset.StandardCharsets*/byte[] data = line.getBytes(StandardCharsets.UTF_8);fos.write(data);line = "像是北五环路蒙住的双眼。";data = line.getBytes(StandardCharsets.UTF_8);fos.write(data); System.out.println("写出完毕!");fos.close();}
}```### 文件输出流-追加模式重载的构造方法可以将文件输出流创建为追加模式- FileOutputStream(String path,boolean append)
- FileOutputStream(File file,boolean append)当第二个参数传入true时,文件流为追加模式,即:指定的文件若存在,则原有数据保留,新写入的数据会被顺序的追加到文件中
用的是UTF-8。 其中中文字3字节表示1个,英文1字节表示1个。