字节流,字符集,字符流
操作本地文件的字节输出流,可以把程序中的数据写入本地文件。
演示:
public class Test01 {
public static void main(String[] args) throws IOException {
//1.创建字节输出流对象
/*
细节:
1.参数是字符串路径或是File对象都可以
2.如果文件不存在,会创建一个新的文件,但要保证父级路径一定存在
3.若文件已存在,构造方法,**会清空文件
*/
FileOutputStream fos = new FileOutputStream("..\\ioDemo\\a.txt");
//2.写数据
/*
细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在AScII上对应的字符
如执意要写当前录入的数字,可以根据Ascii表的对应关系表示:48-0
如:要写数字65
fos.write(54);//6
fos.write(53);//5
*/
fos.write(97)//a
fos.write(98)//b
//3.释放资源:目的是解除资源的占用
fos.close();
}
}
public class Test2 {
public static void main(String[] args) throws IOException {
//1创建字节输出流对象
FileOutputStream fos = new FileOutputStream("..\\ioDemo\\a.txt");
//2写入数据
//字符串表示要写入的数据
String s = "HelloWorld";
//调用getBytes方法,得到字节数组
byte[] bytes = s.getBytes();
//放入字节数组
fos.write(bytes);
//3释放资源
fos.close();
}
}
public class Test3 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("..\\ioDemo\\a.txt");
byte[] bytes = {97, 98, 99};
fos.write(bytes);
fos.close();
}
}
public class Test2 {
public static void main(String[] args) throws IOException {
//1创建字节输出流对象
FileOutputStream fos = new FileOutputStream("..\\ioDemo\\a.txt");
//2写入数据
//字符串表示要写入的数据
String s = "HelloWorld";
//调用getBytes方法,得到字节数组
byte[] bytes = s.getBytes();
//放入字节数组
fos.write(bytes,3,3);//参数2表示开始索引,参数3表示长度
//3释放资源
fos.close();
}
}
在上面的演示中有没有发现一个问题?
public class Test02 {
public static void main(String[] args) throws IOException {
//创建字节流输出对象
FileOutputStream fos=new FileOutputStream("..\\ioDemo\\a.txt");
//写入第一个数据
String str="JAVA";
byte[] bytes = str.getBytes();
fos.write(bytes);
//换行回车
String str2="\r\n";//表示回车、换行
byte[] bytes1 = str2.getBytes();
fos.write(bytes1);
//写入第二个数据
String str3="HelloWorld";
byte[] bytes2 = str3.getBytes();
fos.write(bytes2);
fos.close();
}
}
续写演示:
创建字节流对象时,在第二个参数打开续写开关即可,true
这样就不会清空之前的内容了,
public class Test02 {
public static void main(String[] args) throws IOException {
//创建字节流输出对象
FileOutputStream fos=new FileOutputStream("..\\ioDemo\\a.txt",true);
//换行回车
String str2="\r\n";
byte[] bytes1 = str2.getBytes();
fos.write(bytes1);
//写入第三个数据
String str4="666";
byte[] bytes3 = str4.getBytes();
fos.write(bytes3);
//释放资源
fos.close();
}
}
操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。
书写步骤:
读取就像一个指针,读取一个,指针向后移动一格
public class t01 {
public static void main(String[] args) throws IOException {
//创建
FileInputStream fis=new FileInputStream("..\\ioDemo\\a.txt");
//读取数据,获取的是单个字符对应的ascii码,当然可以强转为字符
int read1 = fis.read();
System.out.println(read1);//97
int read2 = fis.read();
System.out.println((char) read2);// b
int read3 = fis.read();
System.out.println((char) read3);// c
int read4 = fis.read();
System.out.println(read4);//100
int read5 = fis.read();
System.out.println(read5);//101
int read6 = fis.read();
System.out.println(read6);//-1
//释放资源
fis.close();
}
}
上面读数据的方法太慢了,当数据很大时,不断手动调用read方法肯定不合理
public class t02 {
public static void main(String[] args) throws IOException {
/**
*
* 字节输入流的循环读取
*/
//1.创建对象
FileInputStream fis = new FileInputStream("..\\ioDemo\\a.txt");
//2.循环读数据
int len;//定义变量接收
//读取到数据就进入
while((len=fis.read())!=-1){
System.out.print((char) len);
}
fis.close();
//错误演示:错在多次调用了fis.read方法,是的指针发生了偏移
/*
while ((fis.read() != -1)) {
int read = fis.read();
System.out.println(read);
}
fis.close();
*/
}
}
控制台:
abcde
在上面我们只是读取了数据,
现在我们来试试,不但要读取数据,还要将数据输出到另一个位置,即__数据的拷贝
如图:
那么我们现在就用无参的read方法来实现mp4数据的拷贝:
public class t3 {
public static void main(String[] args) throws IOException {
long l = System.currentTimeMillis();//开始时间
//1.字节流输入对象--为了读取
FileInputStream fis=new FileInputStream("E:\\aaa-FIle学习测试\\ccc\\movie.mp4");
//2.字节流输出对象--为了写入
FileOutputStream fos=new FileOutputStream("..\\ioDemo\\Copy.mp4");
//**读取
int b;//定义变量接b收bb
//读取到数据就进入
while((b=fis.read())!=-1){
//**写入
fos.write(b);//读出来的len是对应的ascii,但write方法会自动将数字转为对应字符
}
fos.close();
fis.close();
long l1 = System.currentTimeMillis();//结束时间
long l2 = l1 - l;
System.out.println("花费的毫秒值:"+l2);//花费时间
}
}
控制台:
花费的毫秒值:12048
虽然说拷贝成功,但可以发现拷贝速度是很慢的。
这是因为无参的read方法实际上一次只能读取一个字节的数据。
现在我们就来学read的重载方法
形参是一个字节数组,好比是一个容器
这个字节数组的长度,就规定了每一次调用read方法读取到的数据的字节大小,(即一次读一个字节数组的数据,每次读取会尽可能把数组装满。)每次读取到的元素放入该字节数组
一般将字节数组的长度定义为1024的整数倍,如102410245(五兆)
在改写拷贝代码前,我们先熟悉这个重载方法:
public class t04 {
public static void main(String[] args) throws IOException {
//创建字节流输入对象
FileInputStream fis=new FileInputStream("..\\ioDemo\\a.txt");
//创建字节数组
byte[]arr=new byte[2];//表示一次只读取两个字节,读取到的元素放入该数组
//*开始读取
int num1 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num1);
//***打印当前的字节数组
String str1=new String(arr);
System.out.println(str1);
//读取
int num2 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num2);
//***打印字节数组
String str2=new String(arr);
System.out.println(str2);
//读取
int num3 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num3);//***此时只读取到最后一个元素e
//***打印字节数组
String str3=new String(arr);
System.out.println(str3);//只读取到最后一个元素e,所以只能将cd中的c覆盖,所以打印ed
//若要打印每次获取到的元素可以这样做:String str=new String (arr ,0 , num)
}
}
2-------------------第一次获取了 两字节
ab------------------字节数组内的元素
2------------------第二次获取了 两字节
cd------------------字节数组内的元素
1------------------第二次获取了 一字节
ed------------------因为只读取到最后一个元素e,所以只能将之前cd的c覆盖,所以打印ed
//若要打印每次获取到的元素可以这样做:String str=new String (arr ,0 , num)
0表示开始索引,num表示当前读取到的字节个数
//一次读取一个字节数组
FileInputStream fis=new FileInputStream("..\\ioDemo\\a.txt");
byte[]arr=new byte[2];//表示一次只读取两个字节,读取到的元素放入该数组
//读取
int num1 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num1);
//***打印字节数组
String str1=new String(arr,0,num1);
System.out.println(str1);
//读取
int num2 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num2);
//***打印字节数组
String str2=new String(arr,0,num2);
System.out.println(str2);
//读取
int num3 = fis.read(arr);//返回值表示读取的字节个数
System.out.println(num3);//***此时只读取到最后一个元素e
//***打印字节数组
String str3=new String(arr,0,num3);
System.out.println(str3);
2
ab
2
cd
1
e
正式改进拷贝代码:
public class t5 {
public static void main(String[] args) throws IOException {
/**
*
* 文件拷贝改写
*/
long start = System.currentTimeMillis();//开始时间
//创建字节流输入,输出对象
FileInputStream fis=new FileInputStream("E:\\aaa-FIle学习测试\\ccc\\movie.mp4");
FileOutputStream fos=new FileOutputStream("..\\ioDemo\\Copy.mp4");
byte[]bytes=new byte[1024*1024*5];//一次读取五兆,即表示写入速度,又表示存储位置
int len;//每次的写入字节大小
while((len=fis.read(bytes))!=-1){
fos.write(bytes,0,len);//再将每次写入的数据,输出到目的地
}
//先调用者,后关闭
fos.close();
fis.close();
long end = System.currentTimeMillis();//结束时间
System.out.println((end-start));//花费时间
}
}
225