Java的IO总结

非流式文件类--File类

  从定义看,File类是Object的直接子类,同时它继承了Comparable接口可以进行数组的排序。

File类的操作包括文件的创建、删除、重命名、得到路径、创建时间等,以下是文件操作常用的函数。

 

 

File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。 

File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。

构造函数:
1)File (String   pathname)   
     例:File  f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
2)File (String  parent  ,  String child)
     例:File f2=new  File(“D:\\dir1","FileTest2.txt") ;//  注意:D:\\dir1目录事先必须存在,否则异常
3)File (File    parent  , String child)
     例:File  f4=new File("\\dir3");
          File  f5=new File(f4,"FileTest5.txt");  //在如果 \\dir3目录不存在使用f4.mkdir()先创建

        一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。    
       1)public boolean exists( ) 判断文件或目录是否存在
       2)public boolean isFile( ) 判断是文件还是目录 
       3)public boolean isDirectory( ) 判断是文件还是目录
       4)public String getName( ) 返回文件名或目录名
       5)public String getPath( ) 返回文件或目录的路径。
       6)public long length( ) 获取文件的长度 
       7)public String[ ] list ( ) 将目录中所有文件名保存在字符串数组中返回。 
       File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
       1) public boolean renameTo( File newFile );    重命名文件
       2) public void delete( );   删除文件
       3)  public boolean mkdir( ); 创建目录

流简单概念介绍

在Java程序中,对于数据的输入/输出操作以"流" (stream) 方式进行;
J2SDK提供了各种各样的"流"类,用以获取不同种类的数据;程序中通过标准的方法输入或输出数据。
Java的流类型一般位于java.io包中


流的方向:
输入流:数据源到程序(InputStream、Reader读进来)
输出流:程序到目的地(OutPutStream、Writer写出去)


处理数据单元:
字节流:按照字节读取数据(InputStream、OutputStream)
字符流:按照字符读取数据(Reader、Writer)


功能不同:
节点流:可以直接从数据源或目的地读写数据。
处理流(包装流):不直接连接到数据源或目的地,是其他流进行封装。目的主要是简化操作和提高性能.


节点流和处理流的关系:
节点流处于io操作的第一线,所有操作必须通过他们进行;
处理流可以对其他流进行处理(提高效率或操作灵活性).

字节流基类

1).InputStream

InputStream:字节输入流基类,抽象类是表示字节输入流的所有类的超类。

 常用方法:// 从输入流中读取数据的下一个字节abstract int read()// 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中int read(byte[] b)// 将输入流中最多 len 个数据字节读入 byte 数组int read(byte[] b, int off, int len)// 跳过和丢弃此输入流中数据的 n个字节long skip(long n)// 关闭此输入流并释放与该流关联的所有系统资源void close()

2).OutputStream

OutputStream:字节输出流基类,抽象类是表示输出字节流的所有类的超类。

 常用方法:// 将 b.length 个字节从指定的 byte 数组写入此输出流void write(byte[] b)// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流void write(byte[] b, int off, int len)// 将指定的字节写入此输出流abstract void write(int b)// 关闭此输出流并释放与此流有关的所有系统资源void close()// 刷新此输出流并强制写出所有缓冲的输出字节void flush()

字节流FileInputStream和FileOuputStream

介绍

1).FileInputStream

FileInputStream:字节文件输入流,从文件系统中的某个文件中获得输入字节,用于读取诸如图像数据之类的原始字节流。

 构造方法:// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定FileInputStream(File file)// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径name指定FileInputStream(String name)常用方法:覆盖和重写了父类的的常用方法。

2).FileOutputStream

FileOutputStream:字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。

 构造方法:// 创建一个向指定File对象表示的文件中写入数据的文件输出流FileOutputStream(File file)// 创建一个向指定File对象表示的文件中写入数据的文件输出流FileOutputStream(File file, boolean append)// 创建一个向具有指定名称的文件中写入数据的输出文件流FileOutputStream(String name)// 创建一个向具有指定name的文件中写入数据的输出文件流FileOutputStream(String name, boolean append)常用方法:覆盖和重写了父类的的常用方法。

文件复制

(熟悉操作):

/**
* 功能:文件复制
* 技能:FileInputStream和FileOuputStream
*
* 总结
* 如何创建流
*  InputStream is = new FileInputStream(new File("e:/readme.txt"));
*  OutputStream os = new FileOutputStream(new File("e:\\readme2.txt"));
*
*
* 流使用完毕一定要关闭
*
* 如何使用流
*   n = is.read();
*   os.write(n);
*        
* 缺点:
* @author Administrator
*
*/
public class TestCopy1 {public static void main(String[] args) throws IOException {//创建一个输入流和输出流
//                File file = new File("e:/readme.txt");
//                InputStream is = new FileInputStream(file);InputStream is = new FileInputStream(new File("e:/readme.txt"));
//                File file2 = new File("e:\readme2.txt");
//                OutputStream os = new FileOutputStream(file2);OutputStream os = new FileOutputStream(new File("e:\\readme2.txt"));//使用输入流和输出流完成文件复制int n;//中转站,比较小(水杯)//读一个字节n = is.read();//从输入流读取一个字节的内容赋给nwhile(n != -1){//没有到达末尾//写一个字节os.write(n);//输出一个字节//System.out.print((char)n);//读一个字节n = is.read();}        //关闭输入流和输出流is.close();os.close();}}

正式标准实现:(一次1024)

/**
* 功能:文件复制
* 技能:FileInputStream和FileOuputStream
*
* 总结
* 如何创建流
*  InputStream is = new FileInputStream(new File("e:/readme.txt"));
*  OutputStream os = new FileOutputStream(new File("e:\\readme2.txt"));
*
*
* 流使用完毕一定要关闭
*
* 如何使用流
*   n = is.read();
*         os.write(n);
*        
* 缺点:中转站太小
*
* @author Administrator
*
*/
public class TestCopy2 {public static void main(String[] args) throws IOException {//创建输入流和输出流InputStream fis = new FileInputStream("e:/JDK_API_1_6_zh_CN.CHM");OutputStream fos = new FileOutputStream("e:/JDK_API_1_6_zh_CN2.CHM");//使用输入流和输出流byte [] buf = new byte[1024];//读一次int len = fis.read(buf);//将源文件的内容写入到buf中,返回真实读取的字节数while(len != -1){//写一次//fos.write(buf);//写1024fos.write(buf, 0, len);//读一次len = fis.read(buf);}//关闭输入流和输出流fis.close();fos.close();}}

 

字符流Reader和Writer

字符流基类

1).Reader

Reader:读取字符流的抽象类.

  常用方法:// 读取单个字符int read()// 将字符读入数组int read(char[] cbuf)// 将字符读入数组的某一部分abstract int read(char[] cbuf, int off, int len)// 跳过字符long skip(long n)// 关闭该流并释放与之关联的所有资源abstract void close()

2).Writer

Writer:写入字符流的抽象类.

 常用方法:// 写入字符数组void write(char[] cbuf)// 写入字符数组的某一部分abstract void write(char[] cbuf, int off, int len)// 写入单个字符void write(int c)// 写入字符串void write(String str)// 写入字符串的某一部分void write(String str, int off, int len)// 将指定字符添加到此 writerWriter append(char c)// 将指定字符序列添加到此 writerWriter append(CharSequence csq)// 将指定字符序列的子序列添加到此 writer.AppendableWriter append(CharSequence csq, int start, int end)// 关闭此流,但要先刷新它abstract void close()// 刷新该流的缓冲abstract void flush()

文件复制:

熟悉操作     

/**
*
* 1.字节流可以读写任何文件(文本文件、二进制文件(音频视频图片 chm))
*         字符流只可以读写文本文件(word不是文本文件)
*   但是字符串处理非英文字符文本文件非常方便
*  
* 2.其实只有字节流,没有字符流
*         字符流底层使用的还是字节流
*                Java在字节流基础上提供了字符流,给编程带来便利
*
* 3.字符流如何是英文字符还是中文字符
*                英文占一个字节,最高位是0   0111 0011
*                中文占两个字节,最高位是1   1011 1011 1001 1101
*
* 4.缺陷:没有进行异常处理
*
*
* @author Administrator
*
*/
public class TestCopy1 {public static void main(String[] args) throws IOException {//创建输入流和输出流Reader fr = new FileReader(new File("e:/readme.txt"));Writer fw = new FileWriter(new File("e:\\readme2.txt"));//默认是false 覆盖//Writer fw = new FileWriter(new File("e:\\readme2.txt"), true);//使用输入流和输出流
//                //读一个字符
//                int ch = fr.read();        //中转站是一个字符
//                while(ch !=-1){
//                        //写一个字符
//                        fw.write(ch);
//                        //输出
//                        System.out.println((char)ch);
//                        //读一个字符
//                        ch = fr.read();        
//                }        char cbuf [] = new char[1024];//读一次int len = fr.read(cbuf);//将读取的内容放入cbuf数组,返回的是真正读取的字符个数while(len != -1){//写一次//fw.write(cbuf);fw.write(cbuf, 0, len);//读一次len = fr.read(cbuf);                        }                //关闭输入流和输出流fr.close();fw.close();}}

加上缺陷处理完整版:

/**
*
* 1.字节流可以读写任何文件(文本文件、二进制文件(音频视频图片 chm))
*         字符流只可以读写文本文件(word不是文本文件)
*   但是字符串处理非英文字符文本文件非常方便
*  
* 2.其实只有字节流,没有字符流
*         字符流底层使用的还是字节流
*                Java在字节流基础上提供了字符流,给编程带来便利
*
* 3.字符流如何是英文字符还是中文字符
*                英文占一个字节,最高位是0   0111 0011
*                中文占两个字节,最高位是1   1011 1011 1001 1101
*
* 4.缺陷:没有进行异常处理
*
*
* @author Administrator
*
*/
public class TestCopy2 {public static void main(String[] args){Reader fr = null;Writer fw = null;try {//创建输入流和输出流fr = new FileReader(new File("e:/readme.txt"));fw = new FileWriter(new File("e:\\readme2.txt"));//默认是false 覆盖char cbuf [] = new char[1024];//读一次int len = fr.read(cbuf);//将读取的内容放入cbuf数组,返回的是真正读取的字符个数while(len != -1){//写一次//fw.write(cbuf);fw.write(cbuf, 0, len);//读一次len = fr.read(cbuf);                        }} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{//关闭输入流和输出流try {if(fr != null){fr.close();}                                } catch (IOException e) {e.printStackTrace();}try {if(fw != null){fw.close();}                                } catch (IOException e) {e.printStackTrace();}}}}

缓冲字节流BufferedInputStream和BufferedOuputStream

介绍

BufferedInputStream

字节缓冲输入流,提高了读取效率。

     构造方法:// 创建一个 BufferedInputStream并保存其参数,即输入流in,以便将来使用。BufferedInputStream(InputStream in)// 创建具有指定缓冲区大小的 BufferedInputStream并保存其参数,即输入流in以便将来使用BufferedInputStream(InputStream in, int size)

.BufferedOutputStream

字节缓冲输出流,提高了写出效率。

     构造方法:// 创建一个新的缓冲输出流,以将数据写入指定的底层输出流BufferedOutputStream(OutputStream out)// 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流BufferedOutputStream(OutputStream out, int size)常用方法:// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流void write(byte[] b, int off, int len)// 将指定的字节写入此缓冲的输出流void write(int b)// 刷新此缓冲的输出流void flush()

文件复制

/**
* 功能:文件复制
* 技能:BufferedInputStream和BufferedOuputStream
*
*
* 1.节点流和处理流
*        节点流   FileInputStream  FileOutputStream
*   处理流  BufferedInputStream  BufferedOutputStream
*  
* 2.处理流的好处
*        好处1:提供了性能
*
*
* 3.如何创建处理流
*                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("e:/JDK_API_1_6_zh_CN.CHM")));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("e:\\JDK_API_1_6_zh_CN2.CHM")));* 4.关闭流:只要关闭高层流即可,底层流可以不关闭
*        关闭高层流的会关闭底层流
*
*
* 5.何时将输出缓冲区的内容更新到文件中(刷新 flush)
*
*        1.缓冲区满了,自动刷新
*  2.关闭输出流时,会先刷新再关闭
*  3.不满的时候也可以手动刷新  
*     bos.flush();
*
*
*   public void close() throws IOException {try {flush();//刷新缓冲区} catch (IOException ignored) {}out.close(); //关闭底层流}
*
* @author Administrator
*
*/
public class TestCopy1 {public static void main(String[] args) throws IOException {//创建一个输入流和输出流
//                InputStream is = new FileInputStream(new File("e:/JDK_API_1_6_zh_CN.CHM"));
//                OutputStream os = new FileOutputStream(new File("e:\\JDK_API_1_6_zh_CN2.CHM"));
//                BufferedInputStream bis = new BufferedInputStream(is);//默认输入缓冲区大小8192
//                BufferedOutputStream bos = new BufferedOutputStream(os);//默认输出缓冲区大小8192BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("e:/JDK_API_1_6_zh_CN.CHM")));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("e:\\JDK_API_1_6_zh_CN2.CHM")));//使用输入流和输出流完成文件复制int n;//中转站,比较小(水杯)//读一个字节n = bis.read();//从输入流读取一个字节的内容赋给nwhile(n != -1){//没有到达末尾//写一个字节bos.write(n);//读一个字节n = bis.read();}        //关闭输入流和输出流bis.close();bos.close();}}

缓冲字符流BufferedReader和BufferedWriter

 

1).BufferedReader

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

 构造方法:// 创建一个使用默认大小输入缓冲区的缓冲字符输入流BufferedReader(Reader in)// 创建一个使用指定大小输入缓冲区的缓冲字符输入流BufferedReader(Reader in, int sz)特有方法:// 读取一个文本行String readLine()

2).BufferedWriter

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

 构造方法:// 创建一个使用默认大小输出缓冲区的缓冲字符输出流BufferedWriter(Writer out)// 创建一个使用给定大小输出缓冲区的新缓冲字符输出流BufferedWriter(Writer out, int sz)特有方法:// 写入一个行分隔符void newLine() 

 

文件复制

/**
* 按行读取文件并复制
*
* 只要文本文件才有行的概念  字符流
* 提高速度:缓冲流
* BufferedReader和BufferedWriter
*
*
*
* 1.处理流的好处
*        1.提高性能
*  2.简化操作
*  
* 2.readLine的实现原理
*        底层还是按照字符一个个读取, 由于采用了缓冲区,性能是提高
*  基本思路:*  StringBuilder  builder = new StringBuilder("");*   ch = br.read();*  while(读取的这个字符是换行符的时候){*          builder.append(ch);*          ch = br.read();*  }*  return builder.toString();
*
* 3.bw.newLine(); 不同的操作系统,换行符不同
*        (1)在微软的MS-DOS和Windows中,使用"回车CR('\r')"和"换行LF('\n')"两个字符作为换行符;Windows系统里面,每行结尾是 回车+换行(CR+LF),即"\r\n";(2)Unix系统里,每行结尾只有 换行CR,即"\n";(3)Mac系统里,每行结尾是 回车CR 即'\r'。
*  
*  *
* @author Administrator
*
*/
public class TestCopy2 {public static void main(String[] args) throws IOException {//创建输入流和输出流
//                Reader fr = new FileReader(new File("e:/java基础题目以及答案1.txt"));
//                BufferedReader br = new BufferedReader(fr);
//                Writer fw = new FileWriter(new File("e:/java基础题目以及答案2.txt"));
//                BufferedWriter bw = new BufferedWriter(fw);BufferedReader br = new BufferedReader(new FileReader(new File("e:/java基础题目以及答案1.txt")));BufferedWriter bw = new BufferedWriter(new FileWriter(new File("e:/java基础题目以及答案2.txt")));//使用输入流和输出流//读一行String str = br.readLine();while(str != null){//写一行bw.write(str);bw.newLine();//换一行//读一行str = br.readLine();}                //关闭输入流和输出流                br.close();bw.close();}}

字符转换流

何时使用转换流?

1.    当字节和字符之间有转换动作时;

2.    流操作的数据需要编码或解码时。

 

1).InputStreamReader

InputStreamReader:字节流转字符流,它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

 构造方法:// 创建一个使用默认字符集的 InputStreamReaderInputStreamReader(InputStream in)// 创建使用给定字符集的 InputStreamReaderInputStreamReader(InputStream in, Charset cs)// 创建使用给定字符集解码器的 InputStreamReaderInputStreamReader(InputStream in, CharsetDecoder dec)// 创建使用指定字符集的 InputStreamReaderInputStreamReader(InputStream in, String charsetName)特有方法://返回此流使用的字符编码的名称 String getEncoding() 
/**
*
*
* 功能:将从键盘输入的一行行数据复制到另外一个文件中
*
* 1.转换流
*   InputStreamReader  将InputStream转换成Reader
*   OutputStreamWriter 将OutputStream转换成Writer
*   ReaderInputStream  这个真没有
*   WriterOutputStream  这个也没有
*  
*  
* 2.InputStreamReader到底是个InputStream还是一个Reader
*   Reader reader = new InputStreamReader(is);
*        
*        public class InputStreamReader extends Reader
*
* 3.转换流使用了一个设计模式:适配器(转换器)模式
*  
*   手机耳机口(大口)------------(大头)转换头(小口)------ 耳机(小头)
*
*   Reader(readLine()) ------------   (Reader)转换流InputStreamReader(InputStream)  ---------  InputStream(System.in)
*  *
*
*
* @author Administrator
*
*/
public class TestCopy1 {public static void main(String[] args) throws IOException {//创建输入流和输出流//Reader reader = new FileReader(new File("e:/java基础题目以及答案1.txt"));
//                InputStream is = System.in;
//                Reader reader = new InputStreamReader(is);
//                BufferedReader br = new BufferedReader(reader);Scanner input = new Scanner(System.in);BufferedWriter bw = new BufferedWriter(new FileWriter(new File("e:/java.txt")));//使用输入流和输出流//读一行//        String str = br.readLine();String str = input.next();while(!"bye".equals(str)){ //"null"//写一行bw.write(str);bw.newLine();//换一行//读一行//str = br.readLine();str = input.next();}                //关闭输入流和输出流                //br.close();input.close();bw.close();}}

 

2).OutputStreamWriter

OutputStreamWriter:字节流转字符流。

 构造方法:// 创建使用默认字符编码的 OutputStreamWriterOutputStreamWriter(OutputStream out)// 创建使用给定字符集的 OutputStreamWriterOutputStreamWriter(OutputStream out, Charset cs)// 创建使用给定字符集编码器的 OutputStreamWriterOutputStreamWriter(OutputStream out, CharsetEncoder enc)// 创建使用指定字符集的 OutputStreamWriterOutputStreamWriter(OutputStream out, String charsetName)特有方法://返回此流使用的字符编码的名称 String getEncoding() 

(3).FileReader、FileWriter

 FileReader:InputStreamReader类的直接子类,用来读取字符文件的便捷类,使用默认字符编码。FileWriter:OutputStreamWriter类的直接子类,用来写入字符文件的便捷类,使用默认字符编码。

 性能测试和调优

之前说带缓冲区会快很多,到底是不是这样呢?

我们复制一个MP4文件来测试一下

不带缓冲的用例两秒,这对于一个IO操作来说显然太长了。

我们用带缓冲区的试一下:

可以看到,读取次数一样,时间少了很多。

但是,读取次数还是太多了,我们可以通过扩大byte数组的方式来减少读写次数。

很明显,速度进一步加快。

但是请注意:也不是数组越大越好,视情况而定。

我们确定了数组大小之后,我们还可以设置缓冲区的大小进一步优化时间。

因为我们是从缓冲区读数据,缓冲区从硬盘读数据,形成这个体系可以加快我们的速度。

实际中可以多次调整尝试,确定最优的方案

System类对IO的支持

 针对一些频繁的设备交互,Java语言系统预定了3个可以直接使用的流对象,分别是:

·        System.in(标准输入),通常代表键盘输入。

·        System.out(标准输出):通常写往显示器。

·        System.err(标准错误输出):通常写往显示器。

PrintStream

/**
*
* System.out 是PrintStream类的一个实例
*                public final static PrintStream out = null;
*                                                    Student  stu  = null;
*
* PrintStream 输出流  字节流  处理流
*                打印流只有输出流,没有输入流
*
*
* PrintStream类的方法println() 这个方法功能简直太强大了!!!
*        可以直接讲各种数据类型(基本数据类型、引用数据类型)直接写入到文件中,并且换行。太方便了,太强大了!!
*  不管什么类型,写入到文件中全部变成字符串
*  缺点1: 123#3.14#true#bjsxt  需要使用特殊的字符来区分各个内容,防止混淆
*  缺点2: 123#3.14#true======="123"  "3.14"  "true"  读出来之后都是字符串,还需要将字符串转换成真实类型
*  
*  DataInputStream和DataOutputStream
*
* @author Administrator
*
*/
public class TestPrintStream {public static void main(String[] args) throws FileNotFoundException {//PrintStream ps = System.out;PrintStream ps = new PrintStream(new FileOutputStream(new File("e:/bjsxt.txt")));ps.println(123);ps.println('A');ps.println(3.14);ps.println(true);ps.println("bjsxt");ps.println(new Date().toString());OutputStream os =new FileOutputStream(new File("e:/bjsxt.txt"));//                os.write(一个字节);
//                String datestr = new Date().toString();;
//                byte [] buf = datestr.getBytes();
//                os.write(buf);
//                BufferedWriter bw;
//                bw.newLine();ps.close();}public void method1(){PrintStream ps = System.out;ps.println(123);ps.println('A');ps.println(3.14);ps.println(true);ps.println("111");ps.println(new Date().toString());//                System.out.println(123);
//                System.out.println('A');
//                System.out.println(3.14);
//                System.out.println(true);
//                System.out.println("111");
//                System.out.println(new Date().toString());}}

PrintWriter

/**
*
* 装饰模式
*
*   this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),false);
*
*  减少了子类的数量,是继承的一种替代方案
*
* @author Administrator
*
*/
public class TestPrintWriter {public static void main(String[] args) throws IOException {PrintWriter pw1 = new PrintWriter(new FileWriter("e:/bjsxt.txt"));PrintWriter pw2 = new PrintWriter(new FileOutputStream("e:/bjsxt.txt"));PrintWriter pw3 = new PrintWriter(new File("e:/bjsxt.txt"));PrintWriter pw = new PrintWriter("e:/bjsxt.txt");pw.println(123);pw.println('A');pw.println(3.14);pw.println(true);pw.println("1111t");pw.println(new Date().toString());pw.close();}}

ACM IO 快速读写

输出

第一种使用传统的System.out.println()方式输出。

public class Main {public static void main(String[] args) {long start = System.currentTimeMillis();for(int i=0;i<100000;i++)System.out.println(i);long end = System.currentTimeMillis();System.out.println("time="+(end-start)+"ms");}
}


time=3443ms
显然在ACM中会超时

第二种使用PrintWriter输出:

public class Main {public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static void main(String[] args) {long start = System.currentTimeMillis();for(int i=0;i<100000;i++)out.println(i);out.flush();long end = System.currentTimeMillis();System.out.println("time="+(end-start)+"ms");out.close();}
}


结果:
time=328ms

虽然每次输出的结果会有大致几十毫秒的偏差,但总体上来看,PrintWriter输出要比用System.out.println()输出快上10倍左右。这个结果就比较让人满意了。

输入

Scanner类读取文件(in.txt,里面有从一到一百万的的整数)

public class Main {public static void main(String[] args) throws IOException{Scanner sc = new Scanner(new FileInputStream("in.txt"));long start = System.currentTimeMillis();for(int i=1;i<=1000000;i++)sc.nextInt();long end = System.currentTimeMillis();System.out.println("time="+(end-start)+"ms");}
}


运行结果:

time=2930ms   
大概3秒,实际上如果ACM中真有一百万的数据,若用Scanner读取,还没开始计算,就已经超时了。

用StreamTokenizer读取

public class Main {public static StreamTokenizer in;static {try{in = new StreamTokenizer(new BufferedReader(new InputStreamReader(new FileInputStream("in.txt"))));}catch (Exception e){e.printStackTrace();}}public static int nextInt() throws IOException{ in.nextToken(); return (int)in.nval; }public static void main(String[] args) throws IOException{long start = System.currentTimeMillis();for(int i=1;i<=1000000;i++)nextInt();    //这里仅读取,不输出long end = System.currentTimeMillis();System.out.println("time="+(end-start)+"ms");}
}

运行结果:

time=397ms
要注意的是,用StreamTokenizer读取字符串时,只能读取纯字母字符串,如果包含数字或者其他字符会返回null。这是用StreamTokenizer读取的缺点。但是用它读取数字时没有问题的。

总结一下:
如果数据量比较小,用Scanner是比较方便的
如果数据量很大的话,那么用StreamTokenizer 是一个很好的选择

最后是模板:

import java.io.*;public class Main {public static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in),32768));public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static double nextDouble() throws IOException{ in.nextToken(); return in.nval; }public static float nextFloat() throws IOException{ in.nextToken(); return (float)in.nval; }public static int nextInt() throws IOException{ in.nextToken(); return (int)in.nval; }public static String next() throws IOException{ in.nextToken(); return in.sval;}public static void main(String[] args) throws IOException{
//        获取输入while(in.nextToken()!=StreamTokenizer.TT_EOF){break;}int x = (int)in.nextToken();  //第一个数据应当通过nextToken()获取int y = nextInt();float f = nextFloat();double d = nextDouble();String str = next();//        输出out.println("abc");out.flush();out.close();}
}

至此,Java的IO总结完啦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习(02)-- ANN学习

文章目录目录1.神经网络知识概览1.1深度学习顶会1.2相关比赛1.3神经网络知识概览1.4神经网络编程一般实现过程2.简单神经网络ANN2.1 数据集&#xff1a;2.2 网络结构&#xff1a;2.3 代码实现2.3.1 读取数据&#xff0c;并做处理2.3.2 构建网络结构2.3.3 训练网络目录 1.神经网…

python(11)-if语句,断言assert

分支语句if1.if基本语法2 if语句的嵌套3 比较运算符号4 逻辑运算符&#xff1a;5 整数随机数初应用6 tip7.断言assert1.if基本语法 if语句开发中的应用场景&#xff1a;如果条件成立做一件事情&#xff0c;如果条件不成立做另外一件事情。有了if语句&#xff0c;程序有了分支.…

深度学习(03)-- CNN学习

文章目录目录1.CNN学习2.Keras深度学习框架目录 1.CNN学习 卷积神经网络CNN总结 从神经网络到卷积神经网络&#xff08;CNN&#xff09;我们知道神经网络的结构是这样的&#xff1a; 那卷积神经网络跟它是什么关系呢&#xff1f;其实卷积神经网络依旧是层级网络&#xff0c;…

PaperNotes(1)-Modeling the World from Internet Photo Collections

从网络图片集对世界进行建模AbstractIntroduction2 Previous Work2.1特征匹配2.2 稀疏重建2.3 基于图像建模2.4 基于图像的渲染2.5 图像浏览&#xff0c;检索和注释3 Overview概述4 Reconstructing Cameras and Sparse Geometry&#xff08;相机标定与稀疏重建&#xff09;4.1K…

深度学习(04)-- 典型CNN结构(LeNet5 ,AlexNet)

LeNet5 LeNet5可以说是最早的卷积神经网络了&#xff0c;它发表于1998年&#xff0c;论文原文Gradient-Based Learning Applied to Doucment Recognition作者是Yann Le Cun等。下面对LeNet5网络架构进行简单的说明&#xff0c;有兴趣的同学可以去参考原文&#xff0c;论文原文…

CNN的几种经典模型

本文主要介绍一下CNN的几种经典模型比较。之前自己也用过AlexNet和GoogleNet&#xff0c;网络上关于各种模型的介绍更是形形色色&#xff0c;自己就想着整理一下&#xff0c;以备自己以后查阅方便 LeNet5 先放一张图&#xff0c;我感觉凡是对深度学习有涉猎的人&#xff0c;对…

PaperNotes(2)-Generative Adversarial Net-代码实现资料

Generative Adversarial Nets-生成对抗网络Abstract1.Introduction2.Related work3.Adversarial nets4.Theoretical Results4.1全局最优 pgpdatap_gp_{data}pg​pdata​4.2算法1的收敛性质5.Experiments6.Advantagesa and disadvantages7.Conclusions and future work8.GAN-代码…

深度学习(05)--典型CNN结构(VGG13,16,19)

文章目录目录1.VGG结构2.VGG结构解释3.3*3卷积核的优点4.VGG的muti-scale方法5.VGG的应用目录 1.VGG结构  LeNet5用大的卷积核来获取图像的相似特征  AlexNet用99、1111的滤波器  VGG 巨大的进展是通过依次采用多个 33 卷积&#xff0c;模仿出更大的感受野&#xff08;r…

redis——发布和订阅

频道的订阅和退订 当一个客户端执行 SUBSCRIBE 命令&#xff0c; 订阅某个或某些频道的时候&#xff0c; 这个客户端与被订阅频道之间就建立起了一种订阅关系。 Redis 将所有频道的订阅关系都保存在服务器状态的 pubsub_channels 字典里面&#xff0c; 这个字典的键是某个被订…

redis——事务

Redis 事务可以一次执行多个命令&#xff0c; 并且带有以下三个重要的保证&#xff1a; 批量操作在发送 EXEC 命令前被放入队列缓存。收到 EXEC 命令后进入事务执行&#xff0c;事务中任意命令执行失败&#xff0c;其余的命令依然被执行。在事务执行过程&#xff0c;其他客户端…

深度学习(06)-- Network in Network(NIN)

文章目录目录1.NIN 结构2.MLP卷积3.全局均值池化4.总体网络架构5.NIN补充5.1 广义线性模型&#xff08;GLM&#xff09;的局限性5.2 CCCP层5.3 1*1卷积核作用&#xff08;补充&#xff09;6.手势识别RGB图像--NIN结构目录 1.NIN 结构 2.MLP卷积 传统CNN的局部感受野窗口的运算…

Pytorch(2)-tensor常用操作

tensor常用数学操作1. 随机数1.1 torch.rand() - 均匀分布数字1.2 torch.randn() - 正态分布数字2. 求和2.1 torch.sum(data, dim)2.2 numpy.sum(data, axis)3. 求积3.1 点乘--对应位置相乘3.2 矩阵乘法4. 均值、方差4.1 torch tensor.mean() .std()4.2 numpy array.mean() .st…

深度学习(07)-- 经典CNN网络结构(Inception (v1-v4))

文章目录目录1.Inception介绍1.1 Inception结构1.2 Inception V1(GoogleNet)1.3 Inception V2(Batch Norm)1.4 Inception V3&#xff08;Factorization&#xff09;1.5 Inception V4&#xff08;ResNet&#xff09;1.5 Inception v1~v4 总结1.6 Inception进阶2.Inception实现目…

Python(13)-函数,lambda语句

函数1 函数定义2 函数调用3 函数注释文档4 函数参数4.1 参数列表,默认参数,任意参数4.1.1 无缺省值参数4.1.2&#xff08;部分&#xff09;缺省值参数4.1.3 数量不定形参数4.2 可变对象和不可变对象4.3 作用域4.3.1 globals()函数4.3.2 global 声明变量为全局变量5 函数返回值5…

深度学习(08)-- Residual Network (ResNet)

文章目录目录1.残差网络基础1.1基本概念1.2VGG19、ResNet34结构图1.3 梯度弥散和网络退化1.4 残差块变体1.5 ResNet模型变体1.6 Residual Network补充1.7 1*1卷积核&#xff08;补充&#xff09;2.残差网络介绍&#xff08;何凯明&#xff09;3.ResNet-50(Ng)3.1 非常深的神经网…

redis——命令请求的执行过程

发送命令请求 当用户在客户端中键入一个命令请求时&#xff0c; 客户端会将这个命令请求转换成协议格式&#xff0c; 然后通过连接到服务器的套接字&#xff0c; 将协议格式的命令请求发送给服务器。 读取命令请求 当客户端与服务器之间的连接套接字因为客户端的写入而变得可…

深度学习(09)-- DenseNet

文章目录目录1.DenseNet网络结构2.稠密连接及其优点3.代码实现4.补充说明目录 1.DenseNet网络结构 2.稠密连接及其优点 每层以之前层的输出为输入&#xff0c;对于有L层的传统网络&#xff0c;一共有L个连接&#xff0c;对于DenseNet&#xff0c;则有L*(L1)/2。 这篇论文主要…

redis——缓存击穿/穿透/雪崩

缓存穿透 一般的缓存系统&#xff0c;都是按照key去缓存查询&#xff0c;如果不存在对应的value&#xff0c;就去后端系统查找&#xff08;比如DB&#xff09;。 一些恶意的请求会故意查询不存在的key,请求量很大&#xff0c;就会对后端系统造成很大的压力。这就叫做缓存穿透…

python(15)-window7配置iPython

前提&#xff1a;安装了Pythonanaconda anaconda安装参考&#xff1a;https://www.zhihu.com/question/58033789 在window系统下可以使用两种方法来实现类似与于Linux终端命令运行程序的方法&#xff08;推荐方式2&#xff09;: 1.cmd:自己没有操作过&#xff0c;可以参考下面…

深度学习(10)-- Capsules Networks(CapsNet)

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/malele4th/article/details/79430464 </div><div id"content_views" class"markdown_views"><!-- flowchart 箭头图标 勿删 --&g…