java IO流学习总结-程序员宅基地

https://www.cnblogs.com/hopeyes/p/9736642.html

近期学习了Java的IO流,尝试着总结一下。

java.io 包下的IO流很多:

其中,以Stream结尾的为字节流,以Writer或者Reader结尾的为字符流。所有的输入流都是抽象类IuputStream(字节输入流)或者抽象类Reader(字符输入流)的子类,所有的输出流都是抽象类OutputStream(字节输出流)或者抽象类Writer(字符输出流)的子类。字符流能实现的功能字节流都能实现,反之不一定。如:图片,视频等二进制文件,只能使用字节流读写。

 1、字符流FileReader和FileWriter

FileReader类

构造方法摘要
FileReader(File file) 
          在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(FileDescriptor fd) 
          在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。
FileReader(String fileName) 
          在给定从中读取数据的文件名的情况下创建一个新 FileReader。

 FileWriter类

构造方法摘要
FileWriter(File file) 
          根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(File file, boolean append) 
          根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(FileDescriptor fd) 
          构造与某个文件描述符相关联的 FileWriter 对象。
FileWriter(String fileName) 
          根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append) 
          根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

使用FileReader和FileWriter类完成文本文件复制:

 CopyFile

2、字符缓冲流BufferedReader和BufferedWriter

字符缓冲流具备文本特有的表现形式,行操作

public class BufferedReader extends Reader

(1)从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

(2)可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

(3)通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,

 BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));

(4)将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。 

public class BufferedWriter extends Writer

(1)将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

(2)可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。

(3)该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。

(4)通常 Writer 将其输出立即发送到底层字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,

 PrintWriter out
   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

(5)缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的。

 

 使用BufferedReader和BufferedWriter完成文件复制

 CopyFile2

缓冲区的工作原理:1、使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。2、通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。3、如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。

3、字节流FileInputStream和FileOutputStream 

public class FileInputStream extends InputStream

(1)FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。

(2)FileInputStream 用于读取诸如图像数据之类的原始字节流。

构造方法摘要
FileInputStream(File file) 
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(FileDescriptor fdObj) 
          通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
FileInputStream(String name) 
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

public class FileOutputStream extends OutputStream

(1)文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。(2) FileOutputStream 用于写入诸如图像数据之类的原始字节的流。

构造方法摘要
FileOutputStream(File file) 
          创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append) 
          创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(FileDescriptor fdObj) 
          创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
FileOutputStream(String name) 
          创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append) 
          创建一个向具有指定 name 的文件中写入数据的输出文件流。

例:使用字节流复制图片

复制代码

 1 import java.io.FileInputStream;
 2 import java.io.FileOutputStream;
 3 import java.io.IOException;
 4 
 5 public class CopImg {
 6     public static void main(String[] args) throws IOException {
 7         FileInputStream fin=new FileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg");
 8         FileOutputStream fout=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopy.jpg");
 9         int len=0;
10         byte[] buff=new byte[1024];
11         while((len=fin.read(buff))!=-1) {
12             fout.write(buff, 0, len);
13         }
14         fin.close();
15         fout.close();
16     }
17 }

复制代码

4、字节缓冲流BufferedInputStream和BufferedOutputStream

public class BufferedInputStream extends FilterInputStream

BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。

public class BufferedOutputStream extends FilterOutputStream

该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

例:使用字节缓冲流实现图片的复制

复制代码

 1 import java.io.BufferedInputStream;
 2 import java.io.BufferedOutputStream;
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 
 7 public class CopyImg {
 8     public static void main(String[] args) throws IOException {
 9         BufferedInputStream bfin=new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\Img.jpg"));
10         BufferedOutputStream bfout=new BufferedOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\ImgCopybuff.jpg"));
11         int len=0;
12         byte[] buff=new byte[1024];
13         while((len=bfin.read(buff))!=-1) {
14             bfout.write(buff, 0, len);
15         }
16         bfin.close();
17         bfout.close();
18     }
19 }

复制代码

5、转换流:InputStreamReader和OutputStreamWriter

InputStreamReader和OutputStreamWriter是字符和字节的桥梁,也可称之为字符转换流。原理:字节流+编码。

FileReader和FileWriter作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接使用子类完成操作,简化代码。

一旦要指定其他编码时,不能使用子类,必须使用字符转换流。

 

public class InputStreamReader extends Reader

(1)InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

(2)每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

(3)为了达到最高效率,可以考虑在 BufferedReader 内包装 InputStreamReader。例如:

 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));//重要

 InputStreamReaderDemo

public class OutputStreamWriter extends Writer

(1)OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

(2)每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。

(3)为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:

Writer out = new BufferedWriter(new OutputStreamWriter(System.out));//重要

例如:利用标准输出流将文本输出到命令行

 OutputStreamWriterDemo

 TransStreamDemo

6、打印流PrintWriter和PrintStream

public class PrintWriter extends Writer

(1)向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。不能输出字节,但是可以输出其他任意类型。

(2)与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。

(3)此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用checkError() 是否出现错误。 

复制代码

 1 import java.io.FileWriter;
 2 import java.io.IOException;
 3 import java.io.PrintWriter;
 4 /**
 5  * 注意:创建FileWriter对象时boolean参数表示是否追加;
 6  *              而创建打印流对象时boolean参数表示是否自动刷新
 7  */
 8 public class PrintWriterDemo {
 9     public static void main(String[] args) throws IOException {
10         //PrintWriter pw=new PrintWriter("print.txt");
11         PrintWriter pw=new PrintWriter(new FileWriter("print.txt"),true);
12         pw.write("测试打印流");
13         pw.println("此句之后换行");
14         pw.println("特有功能:自动换行和自动刷新");
15         pw.println("利用构造器设置自动刷新");
16         pw.close();
17     }
18 }

复制代码

使用字符打印流复制文本文件:

 PrintWriterDemo

public class PrintStream extends FilterOutputStreamimplements Appendable, Closeable
(1)PrintStream 为其他输出流添加了功能(增加了很多打印方法),使它们能够方便地打印各种数据值表示形式(例如:希望写一个整数,到目的地整数的表现形式不变。字节流的write方法只将一个整数的最低字节写入到目的地,比如写fos.write(97),到目的地(记事本打开文件)会变成字符'a',需要手动转换:fos.write(Integer.toString(97).getBytes());而采用PrintStream:ps.print(97),则可以保证数据的表现形式)。
1 //PrintStream的print方法 
2  public void print(int i) {
3         write(String.valueOf(i));
4  }
(2)与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。
另外,为了自动刷新,可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,可调用其中一个 println 方法,或写入一个换行符或字节 ('\n')。
(3)PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。  
使用字节打印流复制文本文件:

 PrintStreamDemo

7、对象操作流ObjectInputStream和ObjectOutputStream

public class ObjectOutputStream extends OutputStream implements ObjectOutput,ObjectStreamConstants

(1)ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。只能使用 ObjectInputStream 读取(重构)对象。

(2)只能将支持 java.io.Serializable 接口的对象写入流中。

(3)writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。

构造方法:ObjectOutputStream(OutputStream out)    创建写入指定 OutputStream 的 ObjectOutputStream。

public class ObjectInputStream extends InputStream implements ObjectInput,ObjectStreamConstants

(1)ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

(2)只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流读取。

(3)readObject 方法用于从流读取对象。应该使用 Java 的安全强制转换来获取所需的类型。在 Java 中,字符串和数组都是对象,所以在序列化期间将其视为对象。读取时,需要将其强制转换为期望的类型。 

例:对象读写:

 Student

 ObjectOperate

 ObjectOperate2

序列化接口Serializable的作用:没有方法,不需要覆写,是一个标记接口为了启动一个序列化功能。唯一的作用就是给每一个需要序列化的类都分配一个序列版本号,这个版本号和类相关联。在序列化时,会将这个序列号也一同保存在文件中,在反序列化时会读取这个序列号和本类的序列号进行匹配,如果不匹配会抛出java.io.InvalidClassException.

注意:静态数据不会被序列化,因为静态数据在方法区,不在对象里。

或者使用transient关键字修饰,也不会序列化。

8、SequenceInputStream 

表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

案例:媒体文件切割与合并

复制代码

 1 import java.io.File;
 2 import java.io.FileInputStream;
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 import java.util.Properties;
 6 
 7 public class CutFile {
 8     /**
 9      * 将一个媒体文件切割成碎片
10      * 思路:1、读取源文件,将源文件的数据分别复制到多个文件
11      * 2、切割方式有两种:按照碎片个数切,或者按照指定大小切
12      * 3、一个输入流对应多个输出流
13      * 4、每个碎片都需要编号,顺序不能错
14      * @throws IOException 
15      */
16     public static void main(String[] args) throws IOException {
17         File srcFile=new File("C:\\Users\\Administrator\\Desktop\\Test\\img.jpg");
18         File partsDir=new File("C:\\Users\\Administrator\\Desktop\\cutFiles");
19         splitFile(srcFile,partsDir);
20     
21     }
22     //切割文件
23     private static void splitFile(File srcFile, File partsDir) throws IOException {
24         if(!(srcFile.exists()&&srcFile.isFile())) {
25             throw new RuntimeException("源文件不是正确文件或者不存在");
26         }
27         if(!partsDir.exists()) {
28             partsDir.mkdirs();
29         }
30         FileInputStream fis=new FileInputStream(srcFile);
31         FileOutputStream fos=null;
32         
33         byte[] buf=new byte[1024*60];
34         
35         int len=0;
36         int count=1;
37         while((len=fis.read(buf))!=-1) {
38             //存储碎片文件
39             fos=new FileOutputStream(new File(partsDir,(count++)+".part"));
40             fos.write(buf, 0, len);
41             fos.close();
42         }
43         /*将源文件和切割的信息也保存起来,随着碎片文件一起发送
44          * 信息:源文件的名称
45          * 碎片的个数
46          *将这些信息单独封装到一个文件中
47          *还要一个输出流完成此操作 */
48         
49         String fileName=srcFile.getName();
50         int partCount=count;
51         fos=new FileOutputStream(new File(partsDir,count+".properties"));
52 //        fos.write(("fileName="+fileName+System.lineSeparator()).getBytes());
53 //        fos.write(("fileCount="+Integer.toString(partCount)).getBytes());
54         Properties prop=new Properties();
55         prop.setProperty("fileName", srcFile.getName());
56         prop.setProperty("partCount", Integer.toString(partCount));
57         //将属性集中的信息持久化
58         prop.store(fos, "part file info");
59         fis.close();
60         fos.close();
61         
62     }
63 }

复制代码

 mergeFile

9、用于操作数组和字符串的流对象

ByteArrayInputStream  ByteArrayOutputStream

CharArrayReader   CharArrayWriter

StringReader    StringWriter

关闭这些流都是无效的,因为这些都未调用系统资源,不需要抛IO异常。

 

 View Code

 

10、RandomAccessFile

 View Code

11、File类:

File: 文件和目录路径名的抽象表示形式,File类的实例是不可改变的

(1)File类常用功能

复制代码

File: 文件和目录路径名的抽象表示形式,File类的实例是不可改变的

 * File类的构造方法:
 *             File(String pathname) 将指定的路径名转换成一个File对象
 *             File(String parent,String child) 根据指定的父路径和文件路径创建对象
 *             File(File parent,String child)
 * File类常用功能:
 *             创建:boolean createNewFile():当指定文件(或文件夹)不存在时创建文件并返回true,否则返回false,路径不存在则抛出异常
 *                 boolean mkdir()  :当指定文件(或文件夹)不存在时创建文件夹并返回true,否则返回false
 *                 boolean mkdirs() :创建指定文件夹,所在文件夹目录不存在时,则顺道一块创建
        
 *             删除:boolean delete():删除文件
            注意:要删除一个目录,需要先删除这个目录下的所有子文件和子目录
 *             获取:File getAbsoluteFile()
 *                 File getParentFile()
 *                 String getAbsolutePath()
 *                 String getParent()
 *                 String getPath()
 *                 long lastModified() 
*             判断: boolean exists();
 *                 boolean isAbsolute() 
 *                 boolean isDirectory() 
 *                 boolean isFile() 
 *                 boolean isHidden()    
 *             修改:boolean renameTo(File dest): 将当前File对象所指向的路径修改为指定File所指的路径 (修改文件名称)    

复制代码

案例:打印指定文件(夹)及其所有子目录

复制代码

 1 import java.io.File;
 2 /**
 3  *打印目录
 4  */
 5 public class FileDemo1 {
 6     public static void main(String[] args){
 7         File f=new File("E:\\BaiduNetdiskDownload");
 8         printTree( f,0);
 9     }
10     
11     public static void printTree(File f,int level) {
12         for(int j=0;j<level;j++) {
13             System.out.print("\t");
14         }
15         System.out.println(f.getAbsolutePath());
16         if(f.isDirectory()) {
17             level++;
18             File strs[]=f.listFiles();
19             for(int i=0;i<strs.length;i++) {
20                 File f0=strs[i];
21                 printTree(f0,level+1);
22             }
23         }
24     }
25 }

复制代码

 (2)File类重要方法之过滤器

String[] list()
String[] list(FilenameFilter)
File[] listFiles()
File[] listFiles(FilenameFilter)
File[] listFiles(FileFilter filter)

File类的list方法可以获取目录下的各个文件,传入过滤器还能按照特定需求取出需要的文件。下面来看一下过滤器怎么用的。首先看

String[] list(FilenameFilter)

查看FilenameFilter源码,发现其实是一个接口:

复制代码

public interface FilenameFilter {
    /**
     * Tests if a specified file should be included in a file list.
     *
     * @param   dir    the directory in which the file was found.
     * @param   name   the name of the file.
     * @return  <code>true</code> if and only if the name should be
     * included in the file list; <code>false</code> otherwise.
     */
    boolean accept(File dir, String name);
}

复制代码

那么我们要想使用过滤器,应该先实现接口,假设我们要找某个文件夹下的txt文件:

复制代码

 1 import java.io.File;
 2 import java.io.FilenameFilter;
 3 
 4 public class FileDemo {
 5     public static void main(String[] args) {
 6         File file = new File("C:\\Test");
 7         if(file.isDirectory()) {
 8             String[] list=file.list(new FilenameFilterbytxt());//传入过滤器
 9             for(String l:list) {
10                 System.out.println(l);
11             }
12         }
13     }
14 }
15 
16 class FilenameFilterbytxt implements FilenameFilter{
17     @Override
18     public boolean accept(File dir, String name) {
19         // TODO Auto-generated method stub
20         return name.endsWith(".txt");//当文件名以.txt结尾时返回true.
21     }
22     
23 }

复制代码

但是我们看到第8行代码只是传入了过滤器,那么accept方法是如何被调用的呢?查看

String[] list(FilenameFilter) 的源码:

复制代码

 1  /*list(FilenameFilter)源码解析*/
 2 public String[] list(FilenameFilter filter) {
 3         String names[] = list();//调用list()方法获取所有名称
 4         if ((names == null) || (filter == null)) {
 5             return names; 
 6         }
 7         List<String> v = new ArrayList<>();//用于保存过滤后的文件名
 8         for (int i = 0 ; i < names.length ; i++) {//遍历
 9             //调用filter的accept方法,传入当前目录this和遍历到的名称names[i]
10             if (filter.accept(this, names[i])) {
11                 v.add(names[i]);//满足过滤器条件的添加到集合中
12             }
13         }
14         return v.toArray(new String[v.size()]);//将集合转成数组返回,限定增删操作
15     }                        

复制代码

也就是说,我们实现的accept方法是在构造器中被调用的。

类似地,FileFilter 也是一个接口,采用匿名内部类的方式实现接口,使用File[] listFiles(FileFilter filter)获取目录下所有文件夹:

复制代码

 1 import java.io.File;
 2 import java.io.FileFilter;
 3 
 4 public class FileDemo {
 5     public static void main(String[] args) {
 6         File file = new File("C:\\Test");
 7         if(file.isDirectory()) {
 8             File[] list=file.listFiles(new FileFilter() {
 9                 @Override
10                 public boolean accept(File pathname) {
11                     // TODO Auto-generated method stub
12                     return pathname.isDirectory();
13                 }
14                 
15             });
16             
17             for(File f:list) {
18                 System.out.println(f);
19             }
20         }
21     }
22 }

复制代码

 File[] listFiles(FileFilter filter) 方法的源码如下:

复制代码

 1 /*File[] listFiles(FileFilter filter)源码解析*/
 2  public File[] listFiles(FileFilter filter) {
 3         String ss[] = list();//调用list()获取所有的名称数组
 4         if (ss == null) return null;//健壮性判断,数组为null则返回
 5         ArrayList<File> files = new ArrayList<>();//创建File类型集合
 6         for (String s : ss) {//遍历
 7             File f = new File(s, this);//private File(String child, File parent)私有构造调用
 8             if ((filter == null) || filter.accept(f))//条件判断
 9                 files.add(f);//添加到集合
10         }
11         return files.toArray(new File[files.size()]);//集合转成数组返回
12     }

复制代码

 12、IO流使用规律总结:

 (1)明确要操作的数据是数据源还是数据目的(要读还是要写)

      源:InputStream  Reader

      目的:OutputStream  Writer

 (2)明确要操作的设备上的数据是字节还是文本

      源:

          字节:InputStream

          文本:Reader

      目的:

          字节:OutputStream

          文本:Writer

(3)明确数据所在的具体设备

      源设备:

        硬盘:文件 File开头

        内存:数组,字符串

        键盘:System.in

        网络:Socket

      目的设备:

        硬盘:文件 File开头

        内存:数组,字符串

        屏幕:System.out

        网络:Socket

(4)明确是否需要额外功能?

    需要转换——转换流 InputStreamReader OutputStreamWriter

    需要高效——缓冲流Bufferedxxx

    多个源——序列流 SequenceInputStream

    对象序列化——ObjectInputStream,ObjectOutputStream

    保证数据的输出形式——打印流PrintStream Printwriter

    操作基本数据,保证字节原样性——DataOutputStream,DataInputStream

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_16605855/article/details/88570387

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签