精华内容
下载资源
问答
  • 写这篇博客的原因完全是在学IO流的时候,有感发。 我先解释一下什么叫IO流:...流:由于进行文件操作的时候大多数是用的byte数据,这些数据并不是一次性写入(读取),而是像水龙头那样慢慢的流(想象一下你接水...

    写这篇博客的原因完全是在学IO流的时候,有感而发。

    我先解释一下什么叫IO流:

    • I:指的是InputStream,这是一个抽象类,最常用的子类是FileInputStream
    • O:值得是OutputStream,这也是一个抽象类,最常用的子类是OutputStream
    • 流:由于在进行文件操作的时候大多数是用的byte数据,这些数据并不是一次性写入(读取),而是像水龙头那样慢慢的流(想象一下你接水的场景)

    废话还是不多bb,先来一份简单的代码:

    File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if (!file.exists()){
                file.createNewFile();
            }
    

    其中File.separator指的是当前系统的默认分隔符,这样写的原因是可以保证Java文件在Windows系统运行时和Linux系统运行时都不会出错

    这段代码也很简单,主要就是创建一个文件。

    当然,这都不是重点,重点在下面

    字节输出流OutputStream
    对于Output Stream类来说,它本身定义的是一个抽象类,按照抽象类的原则来讲,需要定义抽象类的子类,而我们要执行的是文件操作,则可以使用FileOutputStream子类来完成。而我们最关心的还是子类中的构造方法

    方法 描述
    public FileOutputStream(File file) throws FileNotFoundException 实例化FileOutputStream,主要用于新建数据
    public FileOutputStream(File file,boolean append) throws FileNotFoundException 实例化FileOutputStream,主要用于追加数据

    我们在实例化OutputStream对象之后肯定要进行输出操作。在OutputStream类中定义了3个输出方法。例如:

    方法 描述
    public abstract void write(int b) throws IOException 输出单个字节数据
    public void write(byte[] b) throws IOException 输出一组字节数据
    public abstract void write(byte[] b,int off,int len) throws IOException 输出部分字节数据

    可能大家在看表的时候已经发现了,都是byte类型的数据。
    使用OutputStream向文件中输出数据。

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if (!file.exists()){
                file.createNewFile();
            }
            OutputStream output=new FileOutputStream(file);// 实例化父类
            String data="Hello World!";
            output.write(data.getBytes());
            output.close();
            }
    }
    

    可以发现,在文件输出的过程中,如果要输出的文件和目录不存在那么会覆盖掉原有的内容,咋办呢?别忘了我们还有一个构造方法专门是为了追加数据的:

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if (!file.exists()){
                file.createNewFile();
            }
            OutputStream output=new FileOutputStream(file,true);// 追加数据
            String data="Hello World!";
            output.write(data.getBytes());
            output.close();
            }
    }
    

    执行一遍会发现,会自动的把数据附加在已有的数据后面。

    我们在来看看另一种类似的流

    字符输出流

    看标题,字节和字符就差一个字,但是,熟悉Java数据基本类型的都知道。这俩货一个是byte,一个是String。那么我们在对文件进行输出操作的时候,就可以把需要输出的内容定义成String类型而不是byte字节型;

    同样,Writer也是一个抽象类,当我们用于文件操作的时候,常用的子类就是FileWriter。我们来看看Writer类的常用方法:

    方法 描述
    public abstract void close() throws IOException 关闭输出流
    public void write(String str) throws IOException 将字符串输出
    public void write(char[] cbuf) throws IOException 将字符数组输出
    public abstract void flush() throws IOException 强制性清空内存

    还是不多bb,上代码,就知道啥样子了:

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if (!file.exists()){
                file.createNewFile();
            }
            Writer out=new FileWriter(file);
            String data="Hello World!";
            out.write(data);
            out.close();
            }
    }
    

    wc,是不是感觉这玩意儿比FileOutputStream简单得多。但是,别那么天真,这玩意儿也有一个弊病,那就是每次在输出文件的时候,总是会覆盖掉原有的文件内容,不信你自己试试就知道了。嘿嘿!

    了解了输出流,我们再来看看输入流;

    Java中的输入流有两种,一种是InputStream,另一种就是Reader。看这名字就知道,md,可能又是一种简单的一种难的。没错,你猜对了;

    字节输入流InputStream
    同样,这货也是一个抽象类,用于文件操作的也是他的子类FileInputStream,当然也有几个方法用于操作文件:

    方法 描述
    public abstract int read() throws IOException 读取单个字节数据,每次执行read()方法都会读取一个数据源的指定数据,如果已经读到了结尾,则会返回-1
    public int read(byte[] b) throws IOException 读取多个字节数据,如果要读取的数据小于byte的数据,这个时候read()方法的返回值int返回的是数据个数,如果现在开辟的字节数组小于读取的长度,且数据已经读取完了。则这个时候返回的是-1
    public int read(byte[] int off,int len) throws IOException 读取指定多个字节数据

    我们还是看看读取内容,具体代码怎么去实现它:

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if(file.exists()){
    		InputStream input=new FileInputStream(file);
    		byte data[] = new byte[1024];// 开辟一个1024长度的byte数组
    		int len=input,read(data);
    		input.close();
    		System.out.println("读取的内容:"+new String(data,0,lem));
    }
            }
    }
    

    上述代码简明的表达了读取文件的全部内容的逻辑,但是想象一下,单个单个的读取怎么做呢?

    这时候需要一点以前的知识了,看看代码:

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if(file.exists()){
            InputStream input=new FileInputStream(file);
            byte data[] = new data[1024];
            int foot=0;// 数组的索引初始值
            int temp=0;// 待会自己看是啥作用
            while((temp=input.read())!=-1){
            data[foot++]=(byte) temp;
            input.close();
            System.out.println("读取到的数据是:"+new String(data,0,foot));
    }
    }
            }
    }
    

    了解了字节输入流,是不是还得了解一下字符输入流。来吧,也别愣着了,码代码呗;

    字符输入流Reader

    那些啥抽象啊,子类啊啥的我都不说了,反正类似,自己慢慢琢磨琢磨。

    看看有哪些方法:

    方法 描述
    public abstract void close() throws IOException 关闭流
    public int read() throws IOException 读取单个字符
    public int read(char[] cbuf) throws IOException 将内容读到字符数组中,返回读入的长度

    有一点和上面的不一样:
    虽然Writer类中提供了输出字符串数据的操作方法,但是在Reader类中并没有这样的定义。之所以会这个样子,完全是因为在使用OutputStream输出数据时,其程序可以输出的大小一定是程序可以承受的数据大小,如果在使用InputStream读取时,可能被读取的数据灰常大,一次性全部读取的话可能会问题,于是就只有一个一个的读取

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            Reader in=new FileReader(file);
            char data[] = new char[1024];
            int len=in.read(data);
            in.close();
            System.out.println("读取的内容:"+new String(data,0,len));
            }
    }
    

    代码写了这么一大堆,我们最后再看看一个问题;

    字节流和字符流的区别

    通过以上的代码演示我们知道了,字节流和字符流都有类似的功能,那么在开发的过程中具体使用哪一种呢?

    他们的区别在于:
    字节流在进行IO操作时,直接针对的时操作的数据终端(如文件),而字符流操作时不是直接针对于终端,而是针对于缓存区(理解为内存)的操作,而后由缓存区来操作终端(如文件),这属于间接操作,按照这样的方式,如果在使用字节流时不关闭最后的输出操作,也可以将所有的内容进行输出,而使用字符流时如果不关闭,则意味着缓冲区的内容不会被输出,当然,这个时候可以由用户自己调用flush()方法去强制性的手动清空
    例如:

    import java.io.*;
    
    public class test {
        public static void main(String[] args) throws Exception{
            File file=new File("e:"+File.separator+"JavaLearn"+File.separator+"EleventhDemo"+File.separator+"1.txt");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("父级目录创建成功");
            }
            if (!file.exists()){
                file.createNewFile();
            }
            Writer out=new FileWriter(file);
            String data="Hello World!";
            out.write(data);
            out.flush();
            }
    }
    

    总结一下,字节流和字符流的主要区别:

    • 字节流没有使用到缓冲区,而字符流使用了;
    • 处理各种数据都可以通过字节流完成,而在处理中午的时候使用字符流会更方便;

    最后,留一个思考题给有兴趣的小伙伴。

    现有一个要求,按照DOS系统的文件拷贝命令,由初始化参数输入源文件和拷贝文件的路径,而后执行操作。

    提示:本程序直接在主方法中完成,不考虑多余的方法和类的设计。考虑大文件的情况(500MB以上)

    我把思路也贴给大家:
    方案一:将要复制的文件全部读取到内存中,而后将所有的内容一次性输出到目标文件;
    方案二:采用边读边写的方式一点一点的进行文件的复制。

    不知道你们会更喜欢哪种方式。

    谢谢观看

    展开全文
  • 注:我觉得好像不是记事本的原因,因为按字节读的话,如果读的是乱码,写入的应该也是乱码。 正是因为字节流没有经过“解码-编码”这个过程,所以不会因为解码和编码使用的编码方式不同产生错误,(字符流会) ...

    为什么print到命令行 中文显示的是乱码,而写到文件里面的中文却能正常显示?
    注:我觉得好像不是记事本的原因,因为按字节读的话,如果读的是乱码,写入的应该也是乱码。

    正是因为字节流没有经过“解码-编码”这个过程,所以不会因为解码和编码使用的编码方式不同而产生错误,(字符流会)
    事实上**,使用字节流能够保证源文件和目标文件是一模一样的,打开文件当然是正常的啦,**
    而打印在屏幕有错是因为你把一个汉字是两个字节的,你的代码把两个字节当作两个字符打印出来,自然是乱码了

    import java.io.*;
    
    public class FileInputStream1 {
    
        public static void main(String[] args) throws Exception {
            FileInputStream in = new FileInputStream(new File("d:\\aaa.txt"));
            FileOutputStream ou = new FileOutputStream(new File("d:\\bb.txt"));
    
            int len;
            byte[] b=new byte[10];
            while ((len = in.read(b)) != -1) {   //代码读到后不清楚几个字节为一个字符   所以打印乱码
                ou.write(b,0,len);
                System.out.print((char)len);   //如果是英文字母则不会乱码,因为英文字母一个字节,Asc码表存在,可直接转char类型  读到的字节转为char即为英文字母
            }
            in.close();
            ou.close();
        }
    }
    

    FileInputStream和FileOutputStream可以直接读写文件(即可以完成copy),但是如果需要在控制台打印读到的字符,需要用InputStreamReader转换流包起来转成字符。

    展开全文
  • 编码”这个过程,所以不会因为解码和编码使用的编码方式不同产生错误,(字符流会)事实上**,使用字节流能够保证源文件和目标文件是一模一样的,打开文件当然是正常的啦,**打印屏幕有错是因为你...

    为什么print到命令行 中文显示的是乱码,而写到文件里面的中文却能正常显示?
    注:我觉得好像不是记事本的原因,因为按字节读的话,如果读的是乱码,写入的应该也是乱码。

    正是因为字节流没有经过“解码-编码”这个过程,所以不会因为解码和编码使用的编码方式不同而产生错误,(字符流会)
    事实上**,使用字节流能够保证源文件和目标文件是一模一样的,打开文件当然是正常的啦,**
    而打印在屏幕有错是因为你把一个汉字是两个字节的,你的代码把两个字节当作两个字符打印出来,自然是乱码了

    import java.io.*;

    public class FileInputStream1 {

    public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream(new File("d:\\aaa.txt"));
    FileOutputStream ou = new FileOutputStream(new File("d:\\bb.txt"));

    int len;
    byte[] b=new byte[10];
    while ((len = in.read(b)) != -1) { //代码读到后不清楚几个字节为一个字符 所以打印乱码
    ou.write(b,0,len);
    System.out.print((char)len); //如果是英文字母则不会乱码,因为英文字母一个字节,Asc码表存在,可直接转char类型 读到的字节转为char即为英文字母
    }
    in.close();
    ou.close();
    }
    }

    FileInputStream和FileOutputStream可以直接读写文件(即可以完成copy),但是如果需要在控制台打印读到的字符,需要用InputStreamReader转换流包起来转成字符。

     

    转载于:https://www.cnblogs.com/peishaobo/p/11347454.html

    展开全文
  • 内容列表从InputStream或者Reader读入数组从OutputStream或者Writer写数组java中常用字节字符数组应用临时存储数据。这些数组又是通常的数据读取来源或者写入目的地。如果你需要程序运行时需要大量...

    内容列表

    从InputStream或者Reader中读入数组

    从OutputStream或者Writer中写数组

    在java中常用字节和字符数组在应用中临时存储数据。而这些数组又是通常的数据读取来源或者写入目的地。如果你需要在程序运行时需要大量读取文件里的内容,那么你也可以把一个文件加载到数组中。当然你可以通过直接指定索引来读取这些数组。但如果设计成为从InputStream或者Reader,而不是从数组中读取某些数据的话,你会用什么组件呢?

    从InputStream或Reader中读取数组

    用ByteArrayInputStream或者CharArrayReader封装字节或者字符数组从数组中读取数据。通过这种方式字节和字符就可以以数组的形式读出了。

    样例如下:

    byte[] bytes = new byte[1024];

    //把数据写入字节数组...

    InputStream input = new ByteArrayInputStream(bytes);

    //读取第一个字节

    int data = input.read();

    while(data != -1) {

    //操作数据

    //读下一个字节

    data = input.read();

    }

    以同样的方式也可以用于读取字符数组,只要把字符数组封装在CharArrayReader上就行了。

    通过OutputStream或者Writer写数组

    同样,也可以把数据写到ByteArrayOutputStream或者CharArrayWriter中。你只需要创建ByteArrayOutputStream或者CharArrayWriter,把数据写入,就像写其它的流一样。当所有的数据都写进去了以后,只要调用toByteArray()或者toCharArray,所有写入的数据就会以数组的形式返回。

    样例如下:

    OutputStream output = new ByteArrayOutputStream();

    output.write("This text is converted to bytes".toBytes("UTF-8"));

    byte[] bytes = output.toByteArray();

    写字符数组也和此例子类似。只要把字符数组封装在CharArrayWriter上就可以了。

    d0c1501a6d8bb921cf36400dc89de69f.png

    展开全文
  • 内容列表从InputStream或者Reader读入数组从OutputStream或者Writer写数组java中常用字节字符数组应用临时存储数据。这些数组又是通常的数据读取来源或者写入目的地。如果你需要程序运行时需要大量...
  • 内容列表从InputStream或者Reader读入数组从OutputStream或者Writer写数组java中常用字节字符数组应用临时存储数据。这些数组又是通常的数据读取来源或者写入目的地。如果你需要程序运行时需要大量...
  • 一、RandomAccessFile字节流之前通过流访问文件都是循序访问的,在某些时候我们需要对文件进行随机访问,就需要借助与RandomAccessFile工具RandomAccessFile类可以在文件中任何位置查找或写入数据RandomAccessFile...
  • Java中的“流”是什么? 一个Java I/O对象叫做数据流。读取数据到内存的对象叫做输入...表示以字节为单位从stream中读取或往stream中写入信息,通常用来读取二进制数据。字符流:以Unicode字符为单位从stream中读取...
  • 内容列表从InputStream或者Reader读入数组从OutputStream或者Writer写数组java中常用字节字符数组应用临时存储数据。这些数组又是通常的数据读取来源或者写入目的地。如果你需要程序运行时需要大量...
  • Java的“流”是什么?...这种分类不是绝对的,例如向一个文件写入数据时,它就是输出流;而在读取数据时,它就是输入流。按照处理数据的单位不同分为字节流和字符流。表示以字节为单位从stream读取或往str...
  • 代码: //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。 FileOutputStream fos = new FileOutputStream(tempString,true)...
  • 流与文件

    2017-11-14 17:32:31
    Java API,从其中读入一个字节序列的对象叫做“输入流”,而可以向其中写入一个字节序列的对象叫做“输出流”。...这些类拥有的读入和写出操作都是基于两字节的Unicode码元,而不是基于单字节字符
  • 13.第十三章 文件.txt

    2019-11-08 16:33:27
    文件使用完毕,应用关闭文件函数把文件关闭,从而把缓冲区的数据写入文件中。否则程序结束时可能造成数据丢失。 fclose函数使用形式: fclose(文件指针); 如:fclose(fp); 正常完成关闭文件操作时,fclose函数...
  • 但是问题来了:既然"錒"的第二个字节是48,而48也ASCII,那么怎么才能区分出我想要的这个48是"錒"的第二字节而不是'H'ASCII字符? PS:我感觉我的markdown语法好像没有错,为什么代码没有高亮 ![图片...
  • //示例程序:记录下Form提交上来的数据,并存储到Log文件中 public class ReceiveServlet extends HttpServlet { public void doPost(HttpServletRequest request,HttpServletResponse response) throws ...
  • 简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。 常见的数据模型 1. 层次结构模型: 层次结构模型实质上是一种有根结点的定向有序树,IMS...
  •  分配出来的内存区域中写入dll路径径。注意第二个参数传递的是MyDllFileBuffer的内容, _  而不是MyDllFileBuffer的内存地址?  If MyReturn = 0 Then Inject = False  MyAddr = GetProcAddress...
  • 中文API支持库(1.0-0

    2009-04-17 08:28:19
    _取系统IN表I小节键值() 获取指定小节(win.ini文件中)所有项名和值的一个列表。返回值,装载到lpReturnedString缓冲区的字符数量。如缓冲区的长度不足以容下所有信息,则返回nSize-2。参考GetPrivateProfileInt...
  • 如果为此参数指定了一个值, 则该值将覆盖 make 文件中的默认值。 值范围: C 编译程序的完整路径。 默认值: 无 remote_dependencies_mode: 说明: 用于指定数据库为远程 PL/SQL 存储的过程处理被依赖对象的方式。如果...
  • 1. 被写入的文件可以用、写、读写,追加方式打开,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符文件首开始。如需保留原有文件内容,希望写入的字符以文件末开始存放,必须以追加方式打开...
  • 1.24 我一个文件中定义了一个extern数组,然后另一个文件中使用,为什么sizeof取不到数组的大小?  声明问题  1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。  *1.26 main的正确定义是...
  • Java之IO流学习总结

    2014-10-19 11:22:20
    ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据, ObjectOutputStream 和所有...
  • 异常-java.io.EOFException

    万次阅读 2019-06-13 10:00:20
    UTF是双字节编码,writeChars方法写入的是按照字符格式写入的,在文件中的占位要小于以Unicode编码的同样字符串,所以,使用readUTF方法读取时,会出现EOF错误 EOFException:当输入过程中意外到达文件或流的末尾...
  • java.io.EOFException

    2020-09-23 21:01:11
    java.io.EOFException EOFException:当输入...2、UTF是双字节编码,writeChars方法写入的是按照字符格式写入的,在文件中的占位要小于以Unicode编码的同样字符串,所以,使用readUTF方法读取时,会出现EOF错误 ...
  • UTF是双字节编码,writeChars方法写入的是按照字符格式写入的,在文件中的占位要小于以Unicode编码的同样字符串,所以,使用readUTF方法读取时,会出现EOF错误 EOFException:当输入过程中意外到达文件或流的末尾...
  • eofexception产生原因:UTF是双字节编码,writeChars方法写入的是按照字符格式写入的,在文件中的占位要小于以unicode编码的同样字符串,所以,使用readUTF方法读取时,会出现EOF错误eofexception:当输入过程中...
  • WinRAR_4.0.exe

    2011-02-04 11:34:33
    压缩文件中查找字符串。 支持下列可选参数: i - 不区分大小写(默认); c - 区分大小写搜索; h - 十六进制搜索; t - 使用 ANSI, Unicode 和 OEM 字符表 (只有 Win32 可用); 如果没有指定任何参数,它...
  • rar压缩软件.rar

    2016-02-13 10:52:44
    压缩文件中查找字符串。 支持下列可选参数: i - 不区分大小写(默认); c - 区分大小写搜索; h - 十六进制搜索; t - 使用 ANSI, Unicode 和 OEM 字符表 (只有 Windows 可用); 如果没有指定任何参数,它...

空空如也

空空如也

1 2 3 4 5 6
收藏数 104
精华内容 41
关键字:

在文件中写入字符而不是字节