IO流 - 字节输入输出流,文件的复制
IO流
- I:input - 输入(读取),eg:把硬盘的内容读取到内存
- O: output - 输出(写入) eg:把内存中的东西写入硬盘保存
- 流:数字(字符/字节) 一般1个字符=2Byte,1Byte = 8bit
字节流可以读取任意文件:音乐/图片/...,
- 抛出文件不存在异常,这里统一throws扔给JVm处理,也可以try catch
字节输出流 -所有字节输出的父类
java.io.OutputStream -字节输出流的顶级抽象父类,有以下几种抽象方法
void close()
关闭此输出流并释放与此流有关的所有系统资源。void flush()
刷新此输出流并强制写出所有缓冲的输出字节。void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。abstract void write(int b)
将指定的字节写入此输出流。
java.io.FileOutpuStream extends OutputStream
FileOutputStream: 文件字节输出流
作用:把把内存中的东西写入文件
构造方法:
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。FileOutputStream(File file, boolean append)
append为追加写开关,true为追加写,false为创建一个新文件构造方法的作用:
- 创建一个FileOutputStream对象
- 会根据构造方法中传递的文件/文件路径,创建一个空的文件
- 会把FileOutputStream对象指向创建好的文件
数据写入原理(内存->硬盘)
- java程序 - JVM虚拟机 - OS - OS调用写数据的方法 - 写入文件
字节输出流的使用步骤
- 创建FileOUtputStream对象,并传递写入数据的目的地
- 调用FileOutputStream对象中的方法,write方法写入文件中
- 流会占用内存,要释放资源
import java.io.FileOutputStream;
import java.io.IOException;
public class IOApi {
public static void main(String[] args) throws IOException {
//构造方法中绑定要写入数据的目的地
FileOutputStream output = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\java_code\\test.txt");
output.write(65); //十进制65 -> 二进制100 0001
/*
任意的文本编辑器,在打开文件时都会查询编码表,把字节表示转换
字符表示
若是0-127,则会查询ASCII表
其他值:查询系统默认表(中文系统查询JDK编码表)
即:上文写入A
*/
//一次写多个字节
output.close();
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOApi {
public static void main(String[] args) throws IOException {
//使用File生成写入数据目的地,相对路径(不使用File也可以)
FileOutputStream output = new FileOutputStream(new File("b.txt"));
output.write(49); //写入三个字节显示为1
output.write(48); //写入三个字节显示为0
output.write(48); //写入三个字节显示为0
output.close();
}
}
连续写入多个字节,优化上述内容
- 如果写的第一个字节是正整数(0-127),那么显示时会查询ASCII码表
- 如果写的第一个是负数,那么第一个字节会和第二个字节显示中文字
符,查询的是系统默认码表(GBK)
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOApi {
public static void main(String[] args) throws IOException {
//使用File生成写入数据目的地,相对路径(不使用File也可以)
FileOutputStream output = new FileOutputStream(new File("b.txt"));
byte[] bytes ={49,48,48};
output.write(bytes); //100
byte[] bytes1 ={-56,78,48};
output.write(bytes1); //100萅0
//public void write(byte[],int off,int len) :把字节数组的一部分写入到文件中
//从偏移量off开始输出到此输出流,从指定的字节数组写入len字节
output.write(bytes,1,2); //100萅000
//String,出现乱码,可能是上面字节与下面字符转换的字节配对
//写在第一行没问题
output.write("你好呀".getBytes()); //00萅000浣犲ソ鍛€
output.close();
}
}
- 数据的追加与换行
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOApi {
public static void main(String[] args) throws IOException {
//打开追加写开关,false创建新文件,覆盖源文件。
FileOutputStream output = new FileOutputStream("b.txt",true);
//String
output.write("你好呀".getBytes());
//Windows: \r\n
//Linux:/n
//Mac:/r
output.write("\n好呀".getBytes());
output.close();
}
}
字节输入流 -所有字节输入的超类
java.io.InputStream extends Object 所有子类的部分共性方法:
abstract int read()
从输入流中读取数据的下一个字节。int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。void close()
关闭此输入流并释放与该流关联的所有系统资源。
java.io.FileInputStream extends InputStream
作用:将硬盘里的文件读取到内存中
构造方法:
- FileInputStream(File file)
file:数据源 - FileInputStream(FileDescriptor fdObj)
通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。 - FileInputStream(String name)
name:文件路径
构造方法的作用:
- 会创建一个FileInputSteam对象
- 会把FileInputStream对象指定的构造方法中要读取的文件
- FileInputStream(File file)
读取数据原理: java程序 - JVM - OS - 调用OS读取数据的方法 - 读取文件
字节输入流步骤
- 创建FileInputStream对象,构造方法中绑定要读取的数据源
- 使用FileInputStream的方法read,读取文件
- 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class IOApi {
public static void main(String[] args) throws IOException {
//相对路径获取数据源
FileInputStream input = new FileInputStream("b.txt");
//使用read方法读取,一次读取一个字节,会返回一个Int值
System.out.println(input.read()); //239 你
//读取的第二个值
System.out.println(input.read()); //187 好
//当input.read返回 -1 时代表读取结束,说明读取到了结束标记
while(input.read() != -1){
System.out.println(input.read());
}
//关闭输入数据流,释放资源
input.close();
}
}
- 字节输入流一次读入多个字节
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区
数组 b 中。
byte[] b:起到缓冲作用,长度一般定义为1024(1kB)或者1024的整数倍
int:返回值是一个有效字节数
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
public class IOApi {
public static void main(String[] args) throws IOException {
//相对路径获取数据源
FileInputStream input = new FileInputStream("b.txt");
//连续读,给定一个字节数组,中文字符如果设置的数组不足够长,会有乱码
//byte[] inp = new byte[10];出现中文乱码,读取不完全
//数组作用:起到缓冲作用
byte[] inp = new byte[20];
//read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,字节数组 b 实际是一个不断重复覆盖的过程
//input.read(inp)返回的是读取的有效字节的个数
System.out.println(input.read(inp)); //19
//使用数组工具类转换为码值
//当数组长度为10时 [-17, -69, -65, -28, -67, -96, -27, -91, -67, -27]
//当数组长度为20时 [-17, -69, -65, -28, -67, -96, -27, -91, -67, -27, -111, -128, 10, -27, -91, -67, -27, -111, -128, 0]
System.out.println(Arrays.toString(inp));
/*
String类的构造方法转换
String[byte[] bytes] : 把字节数组转换为字符串
String(byte[] bytes,int offset,int length)把字符数组的一部分转换为字符串,
offset:偏移位置,length:转换个数
*/
//出现乱码,是因为给的byte[10]长度不够,换为byte[20]正常
//长度为10 你好� ;长度为20 显示正常
//主要是idea中用的UTF-8编码,一个中文需要读取三个字节
System.out.println(new String(inp));
/*********************************************
为什么要用偏移量0,因为如果数组过大,容易浪费空间
所以可以设置长度为input.read(inp)的返回值,也就是19,如下
System.out.println(new String(inp,0,19));
*********************************************/
//关闭输入数据流,释放资源
input.close();
}
}
文件复制
- 原理:一读,一写,凡是字节流文件都可以复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class IOApi {
public static void main(String[] args) throws IOException {
//读,相对路径获取数据源
FileInputStream input = new FileInputStream("b.txt");
byte[] inp = new byte[1024];
//len为读取的有效字节位数
int len = input.read(inp);
//写,相对路径给出文件写入抽象位置
FileOutputStream output = new FileOutputStream("b_copy.txt");
//给出写入数据,从0开始到有效位置结束
output.write(inp,0,len);
//优化代码
FileInputStream inputJpg = new FileInputStream("C:\\Users\\Administrator\\Pictures\\1.jpg");
FileOutputStream outputJpg = new FileOutputStream("C:\\Users\\Administrator\\Pictures\\1_copy.jpg");
//注,中文结束位会报错,陷入死循环,可复制图片,图片大,用字节数组处理快
byte[] bytes= new byte[1024*1024];
int lenJpg = 0;
while((lenJpg = inputJpg.read(bytes)) != -1){
outputJpg.write(bytes,0,lenJpg);
}
//先释放写的,写完一定读完了
outputJpg.close();
inputJpg.close();
}
}
字节流读取中文文件
- 一个中文:GBK编码占用两个字节 UTF-8:占用三个字节
IO流 - 字节输入输出流,文件的复制的更多相关文章
- Java中IO流,输入输出流概述与总结
总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都是抽象类InputStream(字节输入 ...
- java学习笔记IO之字节输入输出流
IO字节输入输出流 OutputStream:字节输出流 该抽象类是所有字节输出流的超类: 定义了一些共性的成员方法: 1.写入一个字节 void write(int b);//b表示字节 2.写入字 ...
- Java自学第10期——File类与IO流(输入输出流、处理流、转换流、缓冲流、Properties集合、打印流)
1.IO简介 IO(输入输出)通过java.io包下的类和接口来支持,包下包括输入.输出两种IO流,每种输入输出流又可分为字符流和字节流两大类. 2.File类 File类是io包下与平台无关的文件和 ...
- Java Io 流(输入输出流)
IO流,也就是输入和输出流,可分为字节流和字符流. 1. 字节流 (1). InputStream 输入流,用于读取文件 输入流常用API: inputStream.read() 读取一个字节 in ...
- IO流07_输入输出流总体系
[javaIO体系中常用的流] [关于字符流和字节流的注意点] 通常,字节流比字符流功能更加强大,因为字节流可以处理所有的二进制文件. 但是字节流来处理字符,又需要将字节转换成字符,增加了编程复杂度. ...
- Java基础IO类之字节输入输出流
一.IO流概述 1.IO流:输入输出流(Input/Output) 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象,即数据在设备间的传输流, 流的本质是数据传输,根据数据传输特性将 ...
- Java修炼——文件字节输入输出流复制和缓冲流复制
一:文件字节输入输出流复制 首先明确数据源和目的文件,然后就是"中转站",最后就是关闭 package com.bjsxt.ioproject; import java.io.Fi ...
- Java IO详解(一)------字节输入输出流
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...
- Java IO详解(三)------字节输入输出流
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...
随机推荐
- idea 2019安装完(打不开&&启动不了)问题解决(最全解决方法)
今天从网盘把idea下载下来后一路安装,准备 设置的时候不管怎么打开 他都无动于衷没办法,卸了安,安了卸,反复折腾了 好几遍 它都无动于衷.于是开始在百度上找答案看了 好几个 方法一遍一遍试还是不行, ...
- Django Mysql数据库-F查询和Q查询
一.F查询和Q查询 F查询: 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较.如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的 ...
- Linux--shell数组和字符串--09
一.数组 数组就是一段连续的变量,一段连续的内存存储空间,为了解决变量过多的问题,在同一类变量中,我们不需要去定义多个名字,而是以数组的方式来定义 1.定义数组 declare -a 定义数组 dec ...
- c语言推箱子 扫雷项目
推箱子 两关的推箱子用到一个三维数组 用到的图片数据如下 https://pan.baidu.com/s/1IDE4GQLo46cxNywDqwxmlQ 密码:jdel 代码如下: #include& ...
- Pycharm2019.2.1永久激活
Pycharm2019.2.1永久激活 Pycharm官网自7月24更新到pycharm2019.2版本后,在短短的一个月内与8月23又带来新版本2019.2.1,不可说更新不快,对于"喜新 ...
- 页面单击按钮弹出modaldialog然后调用ajax处理程序获取数据,给父级页面控件赋值
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RefTopicList.asp ...
- SpringCloud之Feign
[前面的话]书接上文,本文的某些知识依赖我的第一篇SpringCLoud的文章:SpringCloud之Eureka,如果没有看过可以先移步去看一下.另外在微服务架构中,业务都会被拆分成一个个独立的服 ...
- Oracle大量数据更新策略
生产上要修改某个产品的产品代号, 而我们系统是以产品为中心的, 牵一发而动全身, 涉及表几乎覆盖全部, 有些表数据量是相当大的, 达到千万, 亿级别. 单纯的维护产品代号的 SQL 是不难的, 但是性 ...
- yield 实现range()函数
def range(*args,step= 1): args = list(args) if len(args) == 2: yield args[0] while args[0]<args[1 ...
- vue路由菜单权限设置就button权限设置
路由权限的设计思路: 首先,我们的需要校验权限的路由的 url,全部由后端返回,后端会返回当前用户的路由树数组.前端在进入页面前请求接口,把数据拿到: 其次,前端会维护一个路由映射组件的列表,如果路由 ...