当前位置: 首页 > wzjs >正文

网站建设费用包括哪些方面郑州网站推广效果

网站建设费用包括哪些方面,郑州网站推广效果,网站建设色调的,河南郑州旅游网站设计目录 I/O 流概述I/O 流的分类I/O 流的体系 字节 I/O 流FileOutputStream 类基本操作写数据的 3 种方式换行和续写原理基本工作流程原理详细剖析 FileInputStream 类基本操作循环读取文件拷贝小文件拷贝大文件拷贝 I/O 流 概述 定义:I/O流(Input/Output…

目录

  • I/O 流
    • 概述
    • I/O 流的分类
    • I/O 流的体系
  • 字节 I/O 流
    • FileOutputStream 类
      • 基本操作
      • 写数据的 3 种方式
      • 换行和续写
      • 原理
        • 基本工作流程
        • 原理详细剖析
    • FileInputStream 类
      • 基本操作
      • 循环读取
      • 文件拷贝
        • 小文件拷贝
        • 大文件拷贝

I/O 流

概述

定义:I/O流(Input/Output Stream) 是计算机中数据传输的一种抽象概念,用于描述数据在程序和外部设备(如文件、网络、内存等)之间的流动方式。可以将它想象成一条“数据管道”,数据像水流一样在这条管道中连续传输。

作用:I/O 流用于读写文件中的数据(可以是读写文件,或网络中的数据)。

I/O 流中,以程序为参照物进行读写:

  1. 读(Read) → Input(输入)
    • 当程序从外部(如文件、键盘、网络等)获取数据时,称为“读”操作。
    • 例如:读取文件内容、接收用户键盘输入、获取网络数据等。
    • 这属于输入(Input),因为数据是从外部流向程序的。
  2. 写(Write) → Output(输出)
    • 当程序向外部(如文件、屏幕、打印机等)发送数据时,称为“写”操作。
    • 例如:将结果保存到文件、在屏幕上显示信息、发送数据到网络等。
    • 这属于输出(Output),因为数据是从程序流向外部。

I/O 流的分类

流的方向:输入流(读取)和输出流(写出)

操作文件类型:

  • 字节流:能操作所有类型的文件
  • 字符流:只能操作纯文本文件(用 Windows 自带的记事本打开能读懂的文件)

I/O 流的体系

在这里插入图片描述

这四个类为 I/O 流中的超类,但由于是抽象类,无法进行实例化,下面将学习这四个类的子类。

字节 I/O 流

FileOutputStream 类

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中

基本操作

操作步骤

  1. 创建字节输出流对象

    FileOutputStream fos = new FileOutputStream("aaa.txt");
    
  2. 写数据

    fos.write();
    
  3. 释放资源

    fos.close();
    

代码示例

import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建字节输出流对象,可按需修改路径FileOutputStream fos = new FileOutputStream("aaa.txt");// 写数据fos.write(97); // 文件中输出 a// 释放资源fos.close();}
}

注意事项

  1. 操作字节输出流需要抛出异常,可以抛出父类异常 IOException

  2. 创建字节输出流对象

    • 参数可以是字符串表示的路径,也可以是 File 对象

    • 如果文件不存在则创建一个新的文件,但要保证父路径是存在的

    • 如果文件已经存在,则会清空文件原有的内容

  3. 写入数据

    • write() 的参数是整数,但是输出到文件中的是该整数对应的 ASCII 字符
  4. 释放资源

    • 每次使用完流之后都要释放资源,否则资源会被一直占用

写数据的 3 种方式

  • void write(int b) 一次写一个字节数据
  • void write(byte[] b) 一次写一个字节数组数据
  • void write(byte[] b int off,int len) 一次写一个字节数组的部分数据

代码示例:

import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("aaa.txt");// 一次写一个字节数据fos.write(97); // a// 一次写一个字节数组数据byte[] bytes = {97,98,99,100,101};fos.write(bytes); // abcde// 一次写一个字节数组的部分数据fos.write(bytes, 1, 3); // bcdfos.close();}
}

换行和续写

  1. 换行写:写出一个换行符即可
    • Windows —— \r\n
    • Linux —— \n
    • Mac —— \r

代码示例:

import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("aaa.txt");// 写入第一行数据String str1 = "hello";byte[] bytes1 = str1.getBytes();fos.write(bytes1);// 写入换行符String str2 = "\r\n";byte[] bytes2 = str2.getBytes();fos.write(bytes2);// 写入第二行数据String str3 = "world";byte[] bytes3 = str3.getBytes();fos.write(bytes3);fos.close();}
}
  1. 续写

    FileOutputStream 有 2 个可以接收布尔类型参数的构造函数,该布尔参数用于指定是否以追加模式打开文件。当这个参数设为 true 时,新写入的数据就会被添加到文件的末尾,实现续写功能。构造函数的具体形式如下:

    // 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果 append 为 true,则将字节写入文件末尾处,而不是写入文件开始处
    public FileOutputStream(File file, boolean append) throws FileNotFoundException;// 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果 append 为 true,则将字节写入文件末尾处,而不是写入文件开始处
    public FileOutputStream(String name, boolean append) throws FileNotFoundException;
    

代码示例:

import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("aaa.txt",true);// 写入前部分数据String str1 = "hello";byte[] bytes1 = str1.getBytes();fos.write(bytes1);// 写入后部分数据String str2 = " world";byte[] bytes2 = str2.getBytes();fos.write(bytes2);// 输出 "hello world"fos.close();}
}

原理

基本工作流程

FileOutputStream 的主要功能是将字节数据从程序写入到文件中,其基本工作流程如下:

  1. 创建流对象:通过构造函数创建 FileOutputStream 对象,该对象会关联一个文件,后续的写入操作将针对这个文件进行。
  2. 写入数据:调用 FileOutputStreamwrite() 方法将字节数据写入到关联的文件中。
  3. 关闭流:调用 close() 方法关闭流,释放系统资源。
原理详细剖析
  1. 构造函数

    FileOutputStream 提供了多个构造函数,用于创建不同方式关联文件的流对象,常见的构造函数如下:

    // 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果文件存在,则会覆盖原有内容
    public FileOutputStream(File file) throws FileNotFoundException;// 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果 append 为 true,则将字节写入文件末尾处,而不是写入文件开始处
    public FileOutputStream(File file, boolean append) throws FileNotFoundException;// 创建一个向具有指定名称的文件中写入数据的输出文件流。如果文件存在,则会覆盖原有内容
    public FileOutputStream(String name) throws FileNotFoundException;// 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果 append 为 true,则将字节写入文件末尾处,而不是写入文件开始处
    public FileOutputStream(String name, boolean append) throws FileNotFoundException;
    

    在创建 FileOutputStream 对象时,Java 会在操作系统层面打开一个文件描述符,该描述符用于标识和操作文件。

  2. 写入数据

    FileOutputStream 提供了多种 write() 方法用于写入数据,常见的方法如下:

    // 将指定的字节写入此文件输出流
    public void write(int b) throws IOException;// 将 b.length 个字节从指定 byte 数组写入此文件输出流中
    public void write(byte[] b) throws IOException;// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
    public void write(byte[] b, int off, int len) throws IOException;
    

    当调用 write() 方法时,Java 会将数据从用户空间(Java 程序所在的内存空间)复制到内核空间的缓冲区中。内核空间是操作系统管理的内存空间,用于与硬件设备进行交互。

  3. 关闭流

    在使用完 FileOutputStream 后,必须调用 close() 方法关闭流,以释放系统资源。关闭流时,操作系统会将缓冲区中的数据全部写入磁盘,并关闭文件描述符。

    // 关闭此文件输出流并释放与此流有关的所有系统资源
    public void close() throws IOException;
    

FileInputStream 类

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来

基本操作

操作步骤

  1. 创建字节输入流对象

    FileInputStream fis = new FileInputStream("aaa.txt");
    
  2. 读取数据

    fis.read();
    
  3. 释放资源

    fis.close();
    

代码示例

import java.io.FileInputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建字节输入流对象FileInputStream fis = new FileInputStream("aaa.txt");// 读取数据int b = fis.read(); // 文件中的数据为 aSystem.out.println(b); // 输出 97// 释放资源fis.close();}
}

注意事项

  1. 创建字节输入流对象

    • 如果文件不存在,程序直接报错
  2. 读取数据

    • 一次只读一个字节,读出来的是数据对应的 ASCII 数字

    • 读到文件末尾,read() 返回 -1

  3. 释放资源

    • 每次使用完流之后都要释放资源,否则资源会被一直占用

循环读取

import java.io.FileInputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建字节输入流对象FileInputStream fis = new FileInputStream("aaa.txt");// 循环读取int b;while((b = fis.read()) != -1) {System.out.println((char)b);}// 释放资源fis.close();}
}

注意事项

循环体不能写成以下形式:

while(fis.read() != -1) {System.out.println(fis.read());
}

while 循环条件 fis.read() != -1 中调用 fis.read() 方法会读取一个字节,当这个字节不是文件结束标志(即返回值不为 -1)时,循环继续执行。
而在循环体中的 System.out.println(fis.read()); 又再次调用了 fis.read() 方法,这会导致每次循环读取了两个字节:一个用于判断循环条件,一个用于输出。
这就会出现跳过字节读取的情况,比如文件内容是 “abc”,按这个逻辑,循环条件读取了 “a” 后进入循环,循环体又读取 “b” 并输出,下一次循环条件读取 “c” 后进入循环,又试图读取下一个字节(但文件已结束),就可能出现意料之外的结果或错误。

文件拷贝

小文件拷贝

核心思想:边读边写

代码示例

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fis = new FileInputStream("1.mp4");FileOutputStream fos = new FileOutputStream("2.mp4");// 循环读取int b;while((b = fis.read()) != -1) {fos.write(b);}// 释放资源fos.close();fis.close();}
}

注意事项

  1. 创建对象时,文件的后缀名要一致
  2. 释放资源时,先使用的资源要最后释放
大文件拷贝

由于 read() 方法一次只读一个字节数据,如果遇到很大的文件,那么拷贝速度就会很慢,所以我们可以使用 read() 方法的重载形式来拷贝:

  • public int read(byte[] buffer) 一次读一个字节数组数据(每次读取会尽可能把数组装满)

注意事项:数组本身也占用空间,如果创建过大的长度,内存可能奔溃,所以创建数组的时候,长度最好选择 1024B 的整数倍,例如 1024 * 1024 * 5,也就是 5MB

代码示例

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fis = new FileInputStream("aaa.txt"); // 数据为 abcFileOutputStream fos = new FileOutputStream("bbb.txt")// 读取数据byte[] bytes = new byte[3];int len = fis.read(bytes);fos.write(bytes);System.out.println("本次读取到" + len + "字节的数据"); // 3String str = new String(bytes);System.out.println("本次读取的内容为:" + str); // abc// 释放资源fos.close();fis.close();}
}

接下来我们看另一段代码,假设 aaa.txt 中的数据是 abcde,字节数组的长度为 2:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fis = new FileInputStream("aaa.txt");// 读取数据byte[] bytes = new byte[2];int len1 = fis.read(bytes);System.out.println("本次读取到" + len1 + "字节的数据");String str1 = new String(bytes);System.out.println("本次读取的内容为:" + str1);int len2 = fis.read(bytes);System.out.println("本次读取到" + len2 + "字节的数据");String str2 = new String(bytes);System.out.println("本次读取的内容为:" + str2);int len3 = fis.read(bytes);System.out.println("本次读取到" + len3 + "字节的数据");String str3 = new String(bytes);System.out.println("本次读取的内容为:" + str3);int len4 = fis.read(bytes);System.out.println("本次读取到" + len4 + "字节的数据");String str4 = new String(bytes);System.out.println("本次读取的内容为:" + str4);// 释放资源fos.close();fis.close();}
}

运行结果如下:

本次读取到2字节的数据
本次读取的内容为:ab
本次读取到2字节的数据
本次读取的内容为:cd
本次读取到1字节的数据
本次读取的内容为:ed
本次读取到-1字节的数据
本次读取的内容为:ed

问题

  • 为什么第三次读取到 1 字节的数据,却显示读取到的内容为 ed?
  • 为什么第四次数据已经读取完了,却还是显示读取到的内容为 ed?

原因

在第一次读取前,指针指向 a,字节数组内容为空

在这里插入图片描述

第一次读取,字节数组长度为 2,a 和 b 进入数组,所以指针向后移两位到 c

在这里插入图片描述

第二次读取,c 和 d 进入数组,把 a 和 b 覆盖,指针向后移两位到 e

在这里插入图片描述

第三次读取,由于只剩下 e,进入数组后只把 c 覆盖了,但是 d 还在数组里,所以读取到的内容为 ed

在这里插入图片描述

第四次读取,由于在上一次读取时,已经将数据读取完了,不会有新的数据把数组中的内容覆盖,所以输出的内容仍为 ed

在这里插入图片描述

我们可以通过使用字符串的 String(byte[] b int off,int len)方法来解决残留的数据:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fis = new FileInputStream("aaa.txt");FileOutputStream fos = new FileOutputStream("bbb.txt");// 读取数据byte[] bytes = new byte[2];int len1 = fis.read(bytes);System.out.println("本次读取到" + len1 + "字节的数据");String str1 = new String(bytes,0,len1);System.out.println("本次读取的内容为:" + str1);int len2 = fis.read(bytes);System.out.println("本次读取到" + len2 + "字节的数据");String str2 = new String(bytes,0,len2);System.out.println("本次读取的内容为:" + str2);int len3 = fis.read(bytes);System.out.println("本次读取到" + len3 + "字节的数据");String str3 = new String(bytes,0,len3);System.out.println("本次读取的内容为:" + str3);// 释放资源fos.close();fis.close();}
}

程序运行结果如下:

本次读取到2字节的数据
本次读取的内容为:ab
本次读取到2字节的数据
本次读取的内容为:cd
本次读取到1字节的数据
本次读取的内容为:e

那么同理我们可以得到通过使用write(byte[] b int off,int len)方法来解决读取数据时的数据残留,以下是大文件拷贝的代码示例:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamDemo {public static void main(String[] args) throws IOException {// 创建对象FileInputStream fis = new FileInputStream("aaa.txt");FileOutputStream fos = new FileOutputStream("bbb.txt");// 读取数据int len;byte[] bytes = new byte[1024 * 1024 * 5];while((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}// 释放资源fos.close();fis.close();}
}
http://www.dtcms.com/wzjs/479577.html

相关文章:

  • 济南建设网官网首页谷歌优化方法
  • 西安市建网站中国互联网公司排名
  • 幼儿园网站静态模板引流推广平台有哪些
  • 西湖区住房和城乡建设局网站广州seo好找工作吗
  • 做条形码哪个网站比较好济南seo关键词排名工具
  • 长沙优化网站建设百度网站收录入口
  • 网站能搜索到推广app的平台
  • 需要做网站建设的公司dz论坛seo设置
  • 网站短链接怎么做的营销团队公司
  • 电子商务网站建设 课件上海seo优化培训机构
  • 铁威马 Nas 做网站市场营销主要学什么
  • 个人网站建设价格套餐东莞百度快速排名
  • 网站推广途径选择国家市场监督管理总局官网
  • 大连开发区商场seo如何挖掘关键词
  • 福田网站建设方案时事新闻最新
  • 网站页面设置百度app下载最新版本
  • 宁波企业免费建站南京百度提升优化
  • 郑州网站建设注意事项seo搜索引擎优化人才
  • 建设网站企业专业服务百度推广的五大优势
  • 餐厅网站建设方案轻松seo优化排名
  • 北京建设厅官方网站网站页面分析作业
  • 怎么查一个网站是什么程序做的中山网站seo
  • 建设银行临江市支行网站seo优化推广多少钱
  • 两学一做网站登录1688精品货源网站入口
  • 做卖号网站吗网站建设方案书范文
  • 怎么打开google网站电商网络营销
  • 商丘市做网站的公司怎样注册自己的网站
  • 网站建设制作需要多少钱长尾关键词搜索网站
  • 做html网站模板下载地址郴州seo外包
  • 天猫运营培训北京百度关键词优化