java流读写_Java IO流(字节流File读写操作)

字符流:

FileReader

FileWriter

BufferedReader

BufferedWriter

字节流:

InputStream OutputStream

需求,想要操作图片数据,这时就要用到字节流。

1.写数据

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileStream {

public static void main(String[] args) throws IOException

{

writeFile();

}

public static void writeFile() throws IOException

{

FileOutputStream fos = new FileOutputStream("fos.txt");

fos.write("abcde".getBytes());

fos.close();

}

}

50035c1015d0

Snip20190917_21.png

2.读取数据

一、挨个读取

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileStream {

public static void main(String[] args) throws IOException

{

readFile_1();

}

public static void readFile_1() throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

int ch = 0;

while ((ch=fis.read())!=-1)

{

System.out.println((char)ch);

}

fis.close();

}

}

//输出

a

b

c

d

e

二、读取一行

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileStream {

public static void main(String[] args) throws IOException

{

readFile_2();

}

public static void readFile_2() throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

byte[] buf = new byte[1024];

int len = 0;

while ((len = fis.read(buf))!=-1)

{

System.out.println(new String(buf,0,len));

}

fis.close();

}

}

//输出

abcde

三、使用available定义缓冲区。

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileStream {

public static void main(String[] args) throws IOException

{

readFile_3();

}

public static void readFile_3() throws IOException

{

FileInputStream fis = new FileInputStream("fos.txt");

int num = fis.available();

byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区,不用再循环了。

fis.read(buf);

System.out.println(new String(buf));

System.out.println("num="+num);

fis.close();

}

}

//输出

abcde

num=5

复制一个图片

思路:

1.用字节读取流对象和图片关联。

2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。

3.通过循环读写,完成数据的存储。

4.关闭资源。

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class CopyPic {

public static void main(String[] args)

{

FileOutputStream fos = null;

FileInputStream fis = null;

try

{

fos = new FileOutputStream("1.png");

fis = new FileInputStream("landscape.jpg");

byte[] buf = new byte[1024];

int len = 0;

while ((len = fis.read(buf))!= -1)

{

fos.write(buf,0,len);

}

}catch (IOException e)

{

throw new RuntimeException("复制文件失败");

}

finally {

try{

if (fis!=null)

fis.close();

}catch (IOException e)

{

throw new RuntimeException("读取关闭失败");

}

try

{

if (fos!=null)

fos.close();

}catch (IOException e)

{

throw new RuntimeException("写入关闭失败");

}

}

}

}

50035c1015d0

Snip20190918_23.png

演示mp3的复制,通过缓冲区。

BufferedOutputStream

BufferedInputStream

循环每次读取一个字节,有多少个字节读取多少次。再把每一个字节写入到1.mp3中。一共有8098212个字节。每次读取到的这个字节用by来接收,by为int型打印by的值为这个二进制的字节所表示的十进制数,循环里面会进行8098212次计算。

50035c1015d0

Snip20190918_26.png

import java.io.*;

public class CopyMp3 {

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy_1();

long end = System.currentTimeMillis();

System.out.println((end-start) + "毫秒");

}

//通过字节流的缓冲区完成复制

public static void copy_1() throws IOException

{

BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("0.mp3"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("1.mp3"));

int by = 0;

int count = 0;

while ((by=bufis.read())!=-1)

{

count++;

bufos.write(by);

}

System.out.println(count);

bufos.close();

bufis.close();

}

}

//输出

8098212

259毫秒

50035c1015d0

Snip20190918_25.png

自定义缓冲区复制Mp3

import java.io.*;

class MyBufferedInputStream

{

private InputStream in;

private byte[] buf = new byte[1024];

private int pos = 0,count = 0;

MyBufferedInputStream(InputStream in)

{

this.in = in;

}

//一次读一个字节,从缓冲区(字节数组)获取。

public int myRead() throws IOException

{

//通过in对象读取硬盘上数据,并存储在buf中

if (count==0) {

count = in.read(buf);

System.out.println("输出的字节数组长度:"+count);

if (count < 0)

return -1;

pos = 0;

byte b = buf[pos];

count--;

pos++;

System.out.println("读到的字符数组中第"+pos+"个字节十进制表示为:"+b);

return b;

}

else if (count>0)

{

byte b = buf[pos];

count --;

pos++;

System.out.println("读到的字符数组中第"+pos+"个字节十进制表示为:"+b);

return b;

}

return -1;

}

public void myClose()throws IOException

{

in.close();

}

}

public class CopyMp3 {

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy_2();

long end = System.currentTimeMillis();

System.out.println((end-start) + "毫秒");

}

public static void copy_2() throws IOException

{

MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("0.mp3"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("2.mp3"));

int by = 0;

int count = 0;

// System.out.println("第一个字节十进制表示为:"+bufis.myRead());

while ((by=bufis.myRead())!=-1)

{

// System.out.println("当前的字节"+by);

count++;

System.out.println("写入计数"+count);

bufos.write(by);

}

System.out.println("写入的字节数:"+count);

bufos.close();

bufis.myClose();

}

}

//输出

输出的字节数组长度:1024

读到的字符数组中第1个字节十进制表示为:73

写入计数1

读到的字符数组中第2个字节十进制表示为:68

写入计数2

读到的字符数组中第3个字节十进制表示为:51

写入计数3

读到的字符数组中第4个字节十进制表示为:4

写入计数4

读到的字符数组中第5个字节十进制表示为:0

写入计数5

读到的字符数组中第6个字节十进制表示为:0

写入计数6

读到的字符数组中第7个字节十进制表示为:0

写入计数7

读到的字符数组中第8个字节十进制表示为:0

写入计数8

读到的字符数组中第9个字节十进制表示为:0

写入计数9

读到的字符数组中第10个字节十进制表示为:35

写入计数10

读到的字符数组中第11个字节十进制表示为:84

写入计数11

读到的字符数组中第12个字节十进制表示为:83

写入计数12

读到的字符数组中第13个字节十进制表示为:83

写入计数13

读到的字符数组中第14个字节十进制表示为:69

写入计数14

读到的字符数组中第15个字节十进制表示为:0

写入计数15

读到的字符数组中第16个字节十进制表示为:0

写入计数16

读到的字符数组中第17个字节十进制表示为:0

写入计数17

读到的字符数组中第18个字节十进制表示为:15

写入计数18

读到的字符数组中第19个字节十进制表示为:0

写入计数19

读到的字符数组中第20个字节十进制表示为:0

写入计数20

读到的字符数组中第21个字节十进制表示为:3

写入计数21

读到的字符数组中第22个字节十进制表示为:76

写入计数22

读到的字符数组中第23个字节十进制表示为:97

写入计数23

读到的字符数组中第24个字节十进制表示为:118

写入计数24

读到的字符数组中第25个字节十进制表示为:102

写入计数25

读到的字符数组中第26个字节十进制表示为:53

写入计数26

读到的字符数组中第27个字节十进制表示为:53

写入计数27

读到的字符数组中第28个字节十进制表示为:46

写入计数28

读到的字符数组中第29个字节十进制表示为:49

写入计数29

读到的字符数组中第30个字节十进制表示为:57

写入计数30

读到的字符数组中第31个字节十进制表示为:46

写入计数31

读到的字符数组中第32个字节十进制表示为:49

写入计数32

读到的字符数组中第33个字节十进制表示为:48

写入计数33

读到的字符数组中第34个字节十进制表示为:52

写入计数34

读到的字符数组中第35个字节十进制表示为:0

写入计数35

读到的字符数组中第36个字节十进制表示为:0

写入计数36

读到的字符数组中第37个字节十进制表示为:0

写入计数37

读到的字符数组中第38个字节十进制表示为:0

写入计数38

读到的字符数组中第39个字节十进制表示为:0

写入计数39

读到的字符数组中第40个字节十进制表示为:0

写入计数40

读到的字符数组中第41个字节十进制表示为:0

写入计数41

读到的字符数组中第42个字节十进制表示为:0

写入计数42

读到的字符数组中第43个字节十进制表示为:0

写入计数43

读到的字符数组中第44个字节十进制表示为:0

写入计数44

读到的字符数组中第45个字节十进制表示为:0

写入计数45

读到的字符数组中第46个字节十进制表示为:-1

写入的字节数:45

3毫秒

发现的Mp3文件字节有缺省,循环只进行了45次,复制也只复制了45个字节。复制的mp3文件有缺省,打不开。通过打印发现循环只进行了45次就停止了,也就是只读到了45个字节,读到第46个字节的时候返回-1了,跳出循环。说明读到的第46个字节的十进制数为-1,二进制表示为11111111。详情请参考负数的二进制表示。

50035c1015d0

Snip20190919_31.png

为什么读到的第46个字节的二进制为11111111?有什么办法可以避免终止循环?

读到的每一个字符是byte类型1个字节(8个二进制位),但是用int类型4个字节(32个二进制位)接收。类型提升了,但是十进制表示还是保持原值。

11111111 -->提升了一个int类型,那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。

怎么补0呢?

11111111 11111111 11111111 11111111

& 00000000 00000000 00000000 11111111

00000000 00000000 00000000 11111111

所以需要对返回的字节和255(00000000 00000000 00000000 11111111)做与运算。

import java.io.*;

class MyBufferedInputStream

{

private InputStream in;

private byte[] buf = new byte[1024];

private int pos = 0,count = 0;

MyBufferedInputStream(InputStream in)

{

this.in = in;

}

//一次读一个字节,从缓冲区(字节数组)获取。

public int myRead() throws IOException

{

//通过in对象读取硬盘上数据,并存储在buf中

if (count==0) {

count = in.read(buf);

// System.out.println("输出的字节数组长度:"+count);

if (count < 0)

return -1;

pos = 0;

byte b = buf[pos];

count--;

pos++;

// System.out.println("读到的字符数组中第"+pos+"个字节十进制表示为:"+b);

return b & 255;

}

else if (count>0)

{

byte b = buf[pos];

count --;

pos++;

// System.out.println("读到的字符数组中第"+pos+"个字节十进制表示为:"+b);

return b & 0xff;

}

return -1;

}

public void myClose()throws IOException

{

in.close();

}

}

public class CopyMp3 {

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy_2();

long end = System.currentTimeMillis();

System.out.println((end-start) + "毫秒");

}

public static void copy_2() throws IOException

{

MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("0.mp3"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("2.mp3"));

int by = 0;

int count = 0;

// System.out.println("第一个字节十进制表示为:"+bufis.myRead());

while ((by=bufis.myRead())!=-1)

{

// System.out.println("当前的字节"+by);

count++;

// System.out.println("写入计数"+count);

bufos.write(by);

}

System.out.println("写入的字节数:"+count);

bufos.close();

bufis.myClose();

}

}

//输出

写入的字节数:8098212

196毫秒

50035c1015d0

Snip20190921_40.png

50035c1015d0

Snip20190921_41.png

可能会有一个疑问,就是本来只有一个字节的byte类型,最后被写入的时候变成了int类型四个字节?大小变了4倍吗?实际上最后bufos.write(by);的时候又对int类型进行了强制转换,只取了最后8位。write方法只将指定的字节写入此缓冲的输出流。即最后一个字节,最后八位。read方法是读取时候强制转化提升,write方法是强制降低,只取最低八位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值