精华内容
下载资源
问答
  • Java(2)-Java IO输入输出

    万次阅读 多人点赞 2012-04-01 11:28:55
    Java中I/O操作主要是指使用Java进行输入,输出操作.Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的...

     

     

    一.什么是IO


          Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。  

          Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO。

      流IO的好处是简单易用,缺点是效率较低。块IO效率很高,但编程比较复杂。 
          Java IO模型  :
          Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

     

    二.数据流的基本概念


            数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序可以是一段、一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。 

          “流是磁盘或其它外围设备中存储的数据的源点或终点。”

        在电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。这里总结从外存读取数据到内存以及将数据从内存写到外存中。对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。那又怎样把放在外存这个容器内的数据读取到内存这个容器以及怎么把内存这个容器里的数据存到外存中呢?

         在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:

             标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。

        流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。

    总结的基本概念如下:

    1) 数据流

        一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。

      

    2) 输入流(Input  Stream):

          程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道

         

     3) 输出流

        程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

             

    采用数据流的目的就是使得输出输入独立于设备。

    Input  Stream不关心数据源来自何种设备(键盘,文件,网络)
    Output  Stream不关心数据的目的是何种设备(键盘,文件,网络)

    4) 数据流分类:

    流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
     1)  字节流:数据流中最小的数据单元是字节
     2)  字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

     

     

    三. 标准I/O


          Java程序可通过命令行参数与外界进行简短的信息交换,同时,也规定了与标准输入、输出设备,如键盘、显示器进行信息交换的方式。而通过文件可以与外界进行任意数据形式的信息交换。

    1. 命令行参数

    public class TestArgs {
    	public static void main(String[] args) {
    		for (int i = 0; i < args.length; i++) {
    			System.out.println("args[" + i + "] is <" + args[i] + ">");
    		}
    	}
    }

    运行命令:java Java C VB
    运行结果:
    args[0] is <Java>
    args[1] is <C>
    args[2] is <VB>

     

    2. 标准输入,输出数据流

    java系统自带的标准数据流:java.lang.System:

    java.lang.System 
    public final class System  extends Object{ 
       static  PrintStream  err;//标准错误流(输出)
       static  InputStream  in;//标准输入(键盘输入流)
       static  PrintStream  out;//标准输出流(显示器输出流)
    }

    注意:
    (1)System类不能创建对象,只能直接使用它的三个静态成员。
    (2)每当main方法被执行时,就自动生成上述三个对象。

    1) 标准输出流 System.out

       System.out向标准输出设备输出数据,其数据类型为PrintStream。方法:

          Void print(参数)
          Void println(参数)

    2)标准输入流 System.in

        System.in读取标准输入设备数据(从标准输入获取数据,一般是键盘),其数 据类型为InputStream。方法:

            int read()  //返回ASCII码。若,返回值=-1,说明没有读取到任何字节读取工作结束。
             int read(byte[] b)//读入多个字节到缓冲区b中返回值是读入的字节数
    例如:
    import java.io.*;
    public class StandardInputOutput {
    	public static void main(String args[]) {
    		int b;
    		try {
    			System.out.println("please Input:");
    			while ((b = System.in.read()) != -1) {
    				System.out.print((char) b);
    			}
    		} catch (IOException e) {
    			System.out.println(e.toString());
    		}
    	}
    }
    等待键盘输入,键盘输入什么,就打印出什么:

     

    3)标准错误流

       System.err输出标准错误,其数据类型为PrintStream。可查阅API获得详细说明。

        标准输出通过System.out调用println方法输出参数并换行,而print方法输出参数但不换行。println或print方法都通 过重载实现了输出基本数据类型的多个方法,包括输出参数类型为boolean、char、int、long、float和double。同时,也重载实现 了输出参数类型为char[]、String和Object的方法。其中,print(Object)和println(Object)方法在运行时将调 用参数Object的toString方法。

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class StandardInputOutput {
    	public static void main(String args[]) {
    		String s;
    		// 创建缓冲区阅读器从键盘逐行读入数据
    		InputStreamReader ir = new InputStreamReader(System.in);
    		BufferedReader in = new BufferedReader(ir);
    		System.out.println("Unix系统: ctrl-d 或 ctrl-c 退出"
    				+ "\nWindows系统: ctrl-z 退出");
    		try {
    			// 读一行数据,并标准输出至显示器
    			s = in.readLine();
    			// readLine()方法运行时若发生I/O错误,将抛出IOException异常
    			while (s != null) {
    				System.out.println("Read: " + s);
    				s = in.readLine();
    			}
    			// 关闭缓冲阅读器
    			in.close();
    		} catch (IOException e) { // Catch any IO exceptions.
    			e.printStackTrace();
    		}
    	}
    }

     

    四.java.IO层次体系结构


         在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了

          Java I/O主要包括如下几个层次,包含三个部分:

       1.流式部分――IO的主体部分;

       2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

       3.其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

       主要的类如下:

         1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。

         2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

         3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

         Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

         4. Reader(文件格式操作):抽象类,基于字符的输入操作。

         5. Writer(文件格式操作):抽象类,基于字符的输出操作。

         6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作

     

         Java中IO流的体系结构如图:

         

     

     

    五. 非流式文件类--File类


    在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。
     
    作用:File类主要用于命名文件、查询文件属性和处理文件目录。
    public    class   File   extends Object 
        implements Serializable,Comparable
    {}

     

    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( ); 创建目录
     
    例子:

     

    import java.io.File;
    import java.io.IOException;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		File dir = new File("\\root");
    		File f1 = new File(dir, "fileOne.txt");
    		File f2 = new File(dir, "fileTwo.java");
    		// 文件对象创建后,指定的文件或目录不一定物理上存在
    		if (!dir.exists())
    			dir.mkdir();
    		if (!f1.exists())
    			f1.createNewFile();
    		if (!f2.exists())
    			f2.createNewFile();
    		System.out.println("f1's AbsolutePath=  " + f1.getAbsolutePath());
    		System.out.println("f1 Canread=" + f1.canRead());
    		System.out.println("f1's len= " + f1.length());
    		String[] FL;
    		int count = 0;
    		FL = dir.list();
    		for (int i = 0; i < FL.length; i++) {
    			count++;
    			System.out.println(FL[i] + "is in \\root");
    		}
    		System.out.println("there are" + count + "file in //root");
    	}
    
    }

     

    说明:File类的方法:
    (1) exists()测试磁盘中指定的文件或目录是否存在
    (2) mkdir()创建文件对象指定的目录(单层目录)
    (3) createNewFile()创建文件对象指定的文件

    (4) list()返回目录中所有文件名字符串

     

    六. Java.IO流类库


    1. io流的四个基本类

          java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:

    基本数据流的I/O

    输入/输出

    字节流

    字符流

    输入流

    Inputstream

    Reader

    输出流

    OutputStream

    Writer

     
    IO框架:

     

        

     

     Java中其他多种多样变化的流均是由它们派生出来的:

          JDK1.4版本开始引入了新I/O类库,它位于java.nio包中,新I/O类库利用通道和缓冲区等来提高I/O操作的效率。

          在java.io包中, java.io.InputStream 表示字节输入流, java.io.OutputStream表示字节输出流,处于java.io包最顶层。这两个类均为抽象类,也就是说它们不能被实例化,必须生成子类之后才能实现一定的功能。

     

    2. io流的具体分类

    一、按I/O类型来总体分类:

         1. Memory 1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
                       2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream
         2.Pipe管道  实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream
         3.File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream
         4. ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream
         5.DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
         6.Printing 包含方便的打印方法 :PrintWriter、PrintStream
         7.Buffering缓冲  在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream
         8.Filtering 滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过
         9.Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream
        10.Counting计数  在读入数据时对行记数 :LineNumberReader、LineNumberInputStream
        11.Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream
        12.Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

    、按数据来源(去向)分类: 
    1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter 
    2、byte[]:ByteArrayInputStream, ByteArrayOutputStream 
    3、Char[]: CharArrayReader, CharArrayWriter 
    4、String: StringBufferInputStream, StringReader, StringWriter 
    5、网络数据流:InputStream, OutputStream, Reader, Writer 

     

     

    七. 字节流InputStream/OutputStream


     1. InputStream抽象类 

          InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream  的流都是向程序中输入数据的,且数据单位为字节(8bit);

    InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法: 
      (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
      (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的 
      (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。 
      (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用, 
      (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取 
      (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. 

             主要的子类:

            

             1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作     
        2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 
        3) StringBufferInputStream:把一个String对象作为InputStream 
        4) PipedInputStream:实现了pipe的概念,主要在线程中使用 
        5) SequenceInputStream:把多个InputStream合并为一个InputStream 

     

     2.OutputStream抽象类

      OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。 
      1. public void write(byte b[ ]):将参数b中的字节写到输出流。 
      2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。 
      3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。 
      4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。 
      5. public void close( ) : 关闭输出流并释放与流相关的系统资源。 

     

           主要的子类:

            

          1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中 
          2) FileOutputStream:把信息存入文件中 
          3) PipedOutputStream:实现了pipe的概念,主要在线程中使用 
          4) SequenceOutputStream:把多个OutStream合并为一个OutStream 

    流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。

    3. 文件输入流: FileInputStream类

          FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。

     

     

    作用:以文件作为数据输入源的数据流。或者说是打开文件,从文件读数据到内存的类。
    使用方法(1)    
       File  fin=new File("d:/abc.txt"); 
      FileInputStream in=new FileInputStream( fin);

     

    使用方法(2)
       FileInputStream  in=new  FileInputStream(“d: /abc.txt”);

    程序举例:
    将InputFromFile.java的程序的内容显示在显示器上

     

    import java.io.IOException;
    import java.io.FileInputStream;
    ;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try{	
    		       FileInputStream rf=new   FileInputStream("InputFromFile.java");
    		       int n=512;   byte  buffer[]=new  byte[n];   
    		       while((rf.read(buffer,0,n)!=-1)&&(n>0)){
    		           System.out.println(new String(buffer) );
    		        }
    		        System.out.println();
    		        rf.close();
    		} catch(IOException  IOe){	    
    		      System.out.println(IOe.toString());
    		}
    
    	}
    
    }

     

    4.文件输出流:FileOutputStream类

       作用:用来处理以文件作为数据输出目的数据流;或者说是从内存区读数据入文件

          FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。 
      创建一个文件流对象有两种方法: 
      方式1: 
       File   f=new  File (“d:/myjava/write.txt ");
            FileOutputStream  out= new FileOutputStream (f);
      方式2: 
      FileOutputStream out=new FileOutputStream(“d:/myjava/write.txt "); 
      方式3:构造函数将 FileDescriptor()对象作为其参数。 
      FileDescriptor() fd=new FileDescriptor(); 
      FileOutputStream f2=new FileOutputStream(fd); 
      方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。 
      FileOutputStream f=new FileOutputStream("d:/abc.txt",true); 
      注意: (1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。 

     

    程序举例:使用键盘输入一段文章,将文章保存在文件write.txt中
    import java.io.IOException;
    import java.io.FileOutputStream;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try {
    			System.out.println("please Input from      Keyboard");
    			int count, n = 512;
    			byte buffer[] = new byte[n];
    			count = System.in.read(buffer);
    			FileOutputStream wf = new FileOutputStream("d:/myjava/write.txt");
    			wf.write(buffer, 0, count);
    			wf.close(); // 当流写操作结束时,调用close方法关闭流。
    			System.out.println("Save to the write.txt");
    		} catch (IOException IOe) {
    			System.out.println("File Write Error!");
    		}
    	}
    
    }

    5. FileInputStream流和FileOutputStream的应用

    利用程序将文件file1.txt 拷贝到file2.txt中。
    import java.io.File;
    import java.io.IOException;
    import java.io.FileOutputStream;
    import java.io.FileInputStream;
    
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try {
    			File inFile = new File("copy.java");
    			File outFile = new File("copy2.java");
    			FileInputStream finS = new FileInputStream(inFile);
    			FileOutputStream foutS = new FileOutputStream(outFile);
    			int c;
    			while ((c = finS.read()) != -1) {
    				foutS.write(c);
    			}
    			finS.close();
    			foutS.close();
    		} catch (IOException e) {
    			System.err.println("FileStreamsTest: " + e);
    		}
    	}
    
    }
    

     

    6. 缓冲输入输出流 BufferedInputStream/ BufferedOutputStream

            

     

          

           计算机访问外部设备非常耗时。访问外存的频率越高,造成CPU闲置的概率就越大。为了减少访问外存的次数,应该在一次对外设的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问硬盘的次数,提高传输效率。

    BufferedInputStream: BufferedInputStream比FileInputStream多了一个缓冲区。它提供了一个缓冲数组,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快。BufferedInputStream的默认缓冲区大小是8192字节。当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。

    例如:BUFFER_SIZE < 8192时候,BufferedInputStream性能是很高。

    BufferedInputStream  bufferedInput = new BufferedInputStream(new FileInputStream(fileA));
    byte[] buffer = new byte[BUFFER_SIZE];
    int len;
    while ((len = bufferedInput.read(buffer)) > 0){
        System.out.println(new String(buffer, 0, len));
    }

    BUFFER_SIZE > 8192时候, FileInputStream和BufferedInputStream两者效率就没有明显差别了。

    BufferedOutputStream :执行wirte时先写入缓冲区,待缓冲区写满后,系统再写入输出设备。

     

    1)将文件读入内存:

    BufferedInputStreamFileInputStream相接

      FileInputStream in = new  FileInputStream( “file1.txt ” );

      BufferedInputStream bin = new  BufferedInputStreamin); 

    2)将内存写入文件:

    BufferedOutputStream FileOutputStream相接:

    String fileB = "/Users/huangguisu/b.txt";
    FileOutputStream out = new FileOutputStream(fileB);
    BufferedOutputStream bOut = new BufferedOutputStream(out);
    byte[] buffer = {0x1,0x2,0x3};
    bOut.write(buffer);
    bOut.flush();
    bOut.close();


    3)键盘输入流读到内存
    BufferedReader标准的数据流相接 
     InputStreamReader sin = new InputStreamReader (System.in) ;
    BufferedReader bin = new       BufferedReader(sin);
    import java.io.*;
    
    public class ReadWriteToFile {
    	public static void main(String args[]) throws IOException {
    		InputStreamReader sin = new InputStreamReader(System.in);
    		BufferedReader bin = new BufferedReader(sin);
    		FileWriter out = new FileWriter("myfile.txt");
    		BufferedWriter bout = new BufferedWriter(out);
    		String s;
    		while ((s = bin.readLine()).length() > 0) {
    			bout.write(s, 0, s.length());
    		}
    
    	}
    }

    程序说明:
    从键盘读入字符,并写入到文件中BufferedReader类的方法:String readLine()
    作用:读一行字符串,以回车符为结束。
    BufferedWriter类的方法:bout.write(String s,offset,len)
    作用:从缓冲区将字符串s从offset开始,len长度的字符串写到某处。

     

     

    八. 字符流Writer/Reader


            Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    1. Reader抽象类

        用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

           

            1) FileReader :与FileInputStream对应  
               主要用来读取字符文件,使用缺省的字符编码,有三种构造函数: 
          (1)将文件名作为字符串 :FileReader f = new FileReader(“c:/temp.txt”); 
          (2)构造函数将File对象作为其参数。 
                  File f=new file(“c:/temp.txt”); 
                  FileReader f1=new FileReader(f); 
         (3)  构造函数将FileDescriptor对象作为参数 
                FileDescriptor() fd = new FileDescriptor() 
                FileReader f2=new FileReader(fd); 
                   (1) 用指定字符数组作为参数:CharArrayReader(char[]) 
                   (2) 将字符数组作为输入流:CharArrayReader(char[], int, int) 
              读取字符串,构造函数如下: public StringReader(String s); 
            2) CharArrayReader:与ByteArrayInputStream对应  
      3) StringReader : 与StringBufferInputStream对应 
      4) InputStreamReader 
            从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is); 
      5) FilterReader: 允许过滤字符流 
            protected filterReader(Reader r); 
      6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。 
         Public BufferReader(Reader r); 

          主要方法:

          (1)  public int read() throws IOException; //读取一个字符,返回值为读取的字符 

      (2)  public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/ 
      (3)  public abstract int read(char cbuf[],int off,int len) throws IOException; 
      /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/ 

    2. Writer抽象类

         写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

        

          1) FileWrite: 与FileOutputStream对应  
      将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。 
      Public FileWrite(file f); 
      
    2)  chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。 
          Public CharArrayWrite(); 
      3) PrintWrite:生成格式化输出 
          public PrintWriter(outputstream os); 
      4) filterWriter:用于写入过滤字符流 
          protected FilterWriter(Writer w); 
      5) PipedWriter:与PipedOutputStream对应   

          6) StringWriter:无与之对应的以字节为导向的stream  

          主要方法:

      (1)  public void write(int c) throws IOException; //将整型值c的低16位写入输出流 
      (2)  public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流 
      (3)  public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流 
      (4)  public void write(String str) throws IOException; //将字符串str中的字符写入输出流 
      (5)  public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流 
      (6)  flush( ) //刷空输出流,并输出所有被缓存的字节。 
      (7)close()    关闭流 public abstract void close() throws IOException

     

     

    3 .InputStream与Reader差别 OutputStream与Writer差别

     

    InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit)
    Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题

    import java.io.*;
    public class EncodeTest {
        private static void readBuff(byte [] buff) throws IOException {
           ByteArrayInputStream in =new ByteArrayInputStream(buff);
            int data;
            while((data=in.read())!=-1)   System.out.print(data+"  ");
            System.out.println();     in.close();     }
    
       public static void main(String args[]) throws IOException {
           System.out.println("内存中采用unicode字符编码:" );
           char   c='好';
           int lowBit=c&0xFF;     int highBit=(c&0xFF00)>>8;
           System.out.println(""+lowBit+"   "+highBit);
           String s="好";
           System.out.println("本地操作系统默认字符编码:");
           readBuff(s.getBytes());
           System.out.println("采用GBK字符编码:");
           readBuff(s.getBytes("GBK"));
           System.out.println("采用UTF-8字符编码:");      
           readBuff(s.getBytes("UTF-8"));      }
    }
    


    Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存

    Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

     

    4、BufferedInputStream 和BufferedReader区别

    首先虽然都作为一个包装类,但是BufferedReader针对字符流,BufferedInputStream针对字节流

    BufferedInputStream在实现的时候是在自身read方法中提供缓存,是一次取1024或更多字节然后再慢慢读,一个个的返回,它并没有实现读一行的方法

    BufferedReader在实现时通过提供一个readLine方法,使用数组或者stringBuilder存储一行数据,并一次性返回

     

    九. FileWriter类(字符输出流类)


    构造方法:FileWriter fw = new FileWriter(String fileName);//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。

                   如: FileWriter fw = new FileWriter("C:\\1.txt");

                     FileWriter fw = new FileWriter(String fileName,boolean append);//创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。

                   如:FileWriter fw = new FileWriter("C:\\1.txt",ture); //表示在fw对文件再次写入时,会在该文件的结尾续写,并不会覆盖掉。

    主要方法: 

            void write(String str)   //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。此时在使用刷新方法就可以使数据保存到目的文件中去。

            viod flush()                //刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。

            viod close()               //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。

    十. 如何选择IO流


     

    1、确定是数据源和数据目的(输入还是输出

                  源:输入流 InputStream Reader
                  目的:输出流 OutputStream Writer

    2、明确操作的数据对象是否是纯文本

                 是:字符流Reader,Writer
                 否:字节流InputStream,OutputStream

    3、明确具体的设备。

           是硬盘文件:File++:
                  读取:FileInputStream,, FileReader,
                   写入:FileOutputStream,FileWriter
          是内存用数组
                  是byte[]:ByteArrayInputStream, ByteArrayOutputStream
                  是char[]:CharArrayReader, CharArrayWriter
                  是String:StringBufferInputStream(已过时,因为其只能用于String的每个字符都是8位的字符串), StringReader, StringWriter
                  是网络用Socket流: 输入socket.getOutputStream()      输出socket.getInputStream()
                 是键盘:用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印

    4、是否需要转换流

                是,就使用转换流,从Stream转化为Reader,Writer:InputStreamReader,OutputStreamWriter 

    5、是否需要缓冲提高效率

            是就加上Buffered:BufferedInputStream, BufferedOuputStream, BuffereaReader, BufferedWriter
       

    6、是否需要格式化输出

     

    例如:将一个文件中数据存储到另一个文件中。JAVA的文件读取主要有字节流读取和字符流读取两种方式,字节流可以既可以操作文本文件,也可以操作非文本文件,如一些二进制数据(图片,视频,对象),而字符流只能操作文本。
         

    将一个文件中数据存储到另一个文件中:

    1) 数据源和数据目的:读取流,InputStream/Reader  输出:OutputStream/Writer
    2)是否纯文本:是!可以选择Reader Writer和InputStream/OutputStream。
    3)设备:是硬盘文件。Reader体系中可以操作文件的对象是 FileReader FileWriter。
                  FileReader fr = new FileReader("a.txt");  
                  FileWriter fw = new FileWriter("b.txt"); 
    4)是否需要提高效率:是,加Buffer
                 BufferedReader bfr = new BufferedReader(new FileReader("a.txt");  );  
                 BufferedWriter bfw = new BufferedWriter(new FileWriter("b.txt");  );

    package com.javademo.demo.io;
    import java.io.*;
    
    public class IoFileDemo {
        private static int BUFFER_SIZE = 1024;
        public static void main(String[] args) throws Exception {
            IoFileDemo  ioFileDemo = new IoFileDemo();
            String  fileA = "/Users/huangguisu/a.txt";
            String  fileB = "/Users/huangguisu/b.txt";
            ioFileDemo.copyFileWithBufferStream(fileA, fileB);
    
        }
    
        /**
         * 字符流读取:只能操作文本文件
         * @param srcFile
         * @throws IOException
         */
        public String readFile(String srcFile)  throws IOException {
            FileReader fr = new FileReader(srcFile);//读取流
            //不要直接用String直接拼接文本。。效率太低,每次要new新对象,用StringBuilder,StringBuffer都可以
            StringBuffer sb = new StringBuffer();
            char[] buf = new char[10];
            int len;
            //读取文件并把它存入buf中,用len返回读到字符的个数,一直读到结尾
            while ((len = fr.read(buf)) != -1) {
                //buf字符数组里仍有空白没有读入的位置,所以不要直接new String(buf);
                String str = new String(buf,0,len);
                sb.append(str);
            }
            fr.close();
            return  sb.toString();
    
        }
    
        /**
         * 字符流读取和写入:只能操作文本
         * @param srcFile
         * @param dstFile
         * @throws IOException
         */
        public void copyFileWithString(String srcFile, String dstFile)  throws IOException {
            FileReader fr = new FileReader(srcFile);//读取流
            FileWriter fw = new FileWriter(dstFile);//输出流
            char[] buf = new char[10];
            int len;
            //读取文件并把它存入buf中,用len返回读到字符的个数,一直读到结尾
            while ((len = fr.read(buf)) != -1) {
                //buf字符数组里仍有空白没有读入的位置,所以不要直接fw.write(buf);可以直接使用fw.write(buf, 0, len);
                String str = new String(buf,0,len);
                fw.write(str);
            }
            fr.close();
            fw.close();
    
        }
    
        /**
         * 使用buffer读取和写入字符流::只能操作文本
         * @param srcFile
         * @param dstFile
         * @throws IOException
         */
        public void copyFileWithBufferedString(String srcFile, String dstFile)  throws IOException {
            FileReader fr = new FileReader(srcFile);//读取流
            FileWriter fw = new FileWriter(dstFile);//输出流
            //使用Buffer提高效率
            BufferedReader bfr = new BufferedReader(fr);
            BufferedWriter bfw = new BufferedWriter(fw);
    
            String str = null;
            int j = 1;
            while ((str = bfr.readLine()) != null) {
                System.out.println("第" + j + "行内容:" + str);
                bfw.write(str);
                bfw.newLine();//跨平台的换行符
                j++;
            }
            bfr.close();
            bfw.close();
            fr.close();
            fw.close();
    
    
        }
    
        /**
         * 例:将一个二进制数据(图片,视频,对象)文件中数据存储到另一个文件中,只能用xxxStream.
         * 当然也可以读取文本文件。
         * 字节输入流和输出流
         * @param srcFile
         * @param dstFile
         * @throws IOException
         */
        public void copyFileWithStream(String srcFile, String dstFile)  throws IOException {
            FileInputStream finS = new FileInputStream(srcFile);
            FileOutputStream foutS = new FileOutputStream(dstFile);
            int c;
            while ((c = finS.read()) != -1) {
                foutS.write(c);
            }
            //或者
            /*
            byte[] buffer = new byte[1024];
            int len;
            while ((len = finS.read(buffer)) > 0){
                foutS.write(buffer, 0, len);
                len.flush();
            }
            */
            finS.close();
            foutS.close();
        }
    
        /**
         * 使用Buffer
         * @param srcFile
         * @param dstFile
         * @throws IOException
         */
        public void copyFileWithBufferStream(String srcFile, String dstFile) throws IOException{
            FileInputStream finS = new FileInputStream(srcFile);
            FileOutputStream foutS = new FileOutputStream(dstFile);
            BufferedInputStream  bufferedInput = new BufferedInputStream(finS);
            BufferedOutputStream bufferedOutput = new BufferedOutputStream(foutS);
            byte[] buffer = new byte[BUFFER_SIZE];
            int len;
            while ((len = bufferedInput.read(buffer)) > 0){
                bufferedOutput.write(buffer, 0, len);
                bufferedOutput.flush();
            }
    
            bufferedInput.close();
            bufferedOutput.close();
            finS.close();
            foutS.close();
        }
    
        /**
         * BufferedReader则是比InputStreamReader更高级,它封裝了StreamReader类,一次读取取一行的字符
         * @param srcFile
         * @param dstFile
         * @throws IOException
         */
        public void copyFileWithBufferStream2(String srcFile, String dstFile)  throws IOException {
            FileInputStream finS = new FileInputStream(srcFile);
            FileOutputStream foutS = new FileOutputStream(dstFile);
    
            InputStreamReader inputStreamReader = new InputStreamReader(finS,"utf8");
            OutputStreamWriter outputStreamWriter = new  OutputStreamWriter(foutS, "utf8");
            BufferedReader brRead = new BufferedReader(inputStreamReader);
            BufferedWriter brWriter = new BufferedWriter(outputStreamWriter);
            String line = null;
            while((line= brRead.readLine()) != null){
                System.out.println(line);
                brWriter.write(line);
                brWriter.newLine();//跨平台的换行符
                brWriter.flush();//刷新流
            }
            brRead.close();
            brWriter.close();
            finS.close();
            foutS.close();
    
        }
    
    
    }
    

     

    7、网络(socket)数据交互:

    package com.javademo.demo.socket;
    
    import java.io.*;
    import java.net.Socket;
    
    public class SocketClient {
        public static void main(String args[]) throws Exception{
            //1、创建客户端Socket,指定服务器地址和端口
            Socket socket = new Socket("127.0.0.1",10000);
            //2、获取输出流,向服务器端发送信息:由Socket对象得到输出流
            OutputStream output = socket.getOutputStream();//字节输出流
            //构造PrintWriter对象:将输出流包装成打印流
            PrintWriter printWriter = new PrintWriter(output);
            printWriter.write("{'user':'hgs'}");
            printWriter.flush();
    
    
            //3、获取输入流,并读取服务器端的响应信息:由Socket对象得到输入流
            InputStream inputStream = socket.getInputStream();
            //构造相应的BufferedReader对象
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String info = null;
            while((info = bufferedReader.readLine()) != null){
                System.out.println("Hello,我是客户端,服务器说:"+info);
            }
    
            //4、由系统标准输入设备构造BufferedReader对象
            BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in));
            String readline;
            readline= stdIn.readLine(); //从系统标准输入读入一字符串
            //若从标准输入读入的字符串为 "ok"则停止循环
            while(!readline.equals("ok")){
                //将从系统标准输入读入的字符串输出到Server
                printWriter.println(readline);
                //刷新输出流,使Server马上收到该字符串
                printWriter.flush();
                //在系统标准输出上打印读入的字符串
                System.out.println("Client:"+readline);
                //从Server读入一字符串,并打印到标准输出上
                System.out.println("Server:"+bufferedReader.readLine());
                readline = stdIn.readLine(); //从系统标准输入读入一字符串
            }
    
        }
    }

     

    11. IOException异常类的子类


    1.public class  EOFException :
       非正常到达文件尾或输入流尾时,抛出这种类型的异常。
    2.public class FileNotFoundException:
       当文件找不到时,抛出的异常。
    3.public class InterruptedIOException:
       当I/O操作被中断时,抛出这种类型的异常。




     

    感谢您的支持,我会继续努力的! 扫码打赏,你说多少就多少

             

     

     

     

    展开全文
  • 第三版信息系统项目管理师47个过程的输入输出及工具

    一、项目整体管理

    过程名

    输入

    工具和技术

    输出

    1、制定项目章程

     

    1、项目工作说明书

    2、商业论证

    3、协议(合同,备忘录、意向及协议书)

    4、组织过程资产

    5、事业环境因素

    1、专家判断

    2、引导技术

     

    1、项目章程

     

    2、制定项目管理计划

     

    1、  项目章程

    2、  其他规划过程的输出

    3、  组织过程资产

    4、  事业环境因素

    1、 专家判断

    2、  引导技术

    1、项目管理计划

     

    3、指导与管理项目工作

    1、项目管理计划

    2、批准的变更请求

    3、组织过程资产

    4、事业环境因素

     

     

    1、  专家判断

    2、  项目管理信息系统(PMIS)

    3、  会议

    1、  可交付成果

    2、  工作绩效数据

    3、  变更请求

    4、  项目管理计划更新

    5、  项目文件更新

    4、监控项目工作

    1、  项目管理计划

    2、  进度预测

    3、  成本预测

    4、  确认的变更

    5、  工作绩效信息

    6、  组织过程资产

    7、  事业环境因素

     

    1、  分析技术

    2、  项目管理信息系统

    3、  会议

    4、  专家判断

     

    1、  变更请求

    2、  工作绩效报告

    3、  项目管理计划更新

    4、  项目文件更新

    5、实施整体变更控制

    1、  项目管理计划

    2、  工作绩效报告

    3、  变更请求

    4、  组织过程资产

    5、  事业环境因素

    1、  会议

    2、  变更控制工具

    3、  专家判断

    1、  批准的变更请求

    2、  变更日志

    3、  项目管理计划更新

    4、  项目文件更新

    结束项目或阶段

    1、  项目管理计划

    2、  验收的可交付成果

    3、  组织过程资产

    1、  分析技术

    2、  会议

    3、  专家判断

    1、  最终产品、服务或成果

    2、  组织过程资产更新

     

    二、项目范围管理

     

    过程名

    输入

    工具和技术

    输出

    1、编制范围管理计划(规划范围管理)

    1、  项目管理计划

    2、  项目章程

    3、  组织过程资产

    4、  事业环境因素

    1、  会议

    2、  专家判断

    1、范围管理计划

    2、需求管理计划

    2、收集需求

    1、  范围管理计划

    2、  需求管理计划

    3、  干系人管理计划

    4、  项目章程

    5、  干系人登记册

    1、  访谈

    2、  焦点小组

    3、  引导式研讨会

    4、  群体创新技术

    5、  群体决策技术

    6、  问卷调查

    7、  观察

    8、  原型法

    9、  标杆对照

    10、系统交付图

    11、文件分析

    1、需求文件

    2、需求跟踪矩阵

    3、定义范围

    1、  范围管理计划

    2、  项目章程

    3、  需求文件

    4、  组织过程资产

    1、  产品分析

    2、  专家判断

    3、  备选方案生成

    4、  引导式研讨会

    1、  项目范围说明书

    2、  项目文件更新

    4、创建工作分解结构(WBS)

    1、  范围管理计划

    2、  项目范围说明书

    3、  需求文件

    4、  事业环境因素

    5、  组织过程资产

    1、  分解

    2、  专家判断

    1、  范围基准

    2、  项目文件更新

    5、确认范围

    1、  项目管理计划

    2、  需求文件

    3、  需求跟踪矩阵

    4、  核实的可交付成果

    5、  工作绩效数据

    1、  检查

    2、  群体决策技术

    1、  验收的可交付成果

    2、  变更请求

    3、  工作绩效信息

    4、  项目文件更新

    6、范围控制

    1、  项目管理计划

    2、  需求文件

    3、  需求跟踪矩阵

    4、  工作绩效数据

    5、  组织过程资产

    1、偏差分析

    1、工作绩效信息

    2、变更请求

    3、项目文件更新

    4、项目管理计划更新

    5、组织过程资产更新

     

     

     

    三、项目时间管理

     

    过程名

    输入

    工具和技术

    输出

    1、规划进度管理

    1、 项目管理计划

    2、 项目章程

    3、 组织过程资产

    4、 事业环境因素

    1、 专家判断

    2、 分析技术

    3、 会议

    1、 项目进度管理计划

     

    2、定义活动

    1、 进度管理计划

    2、 范围基准

    3、 组织过程资产

    4、 事业环境因素

    1、 分解

    2、 滚动式规划

    3、 专家判断

    1、 活动清单

    2、 活动属性

    3、 里程碑清单

    3、排列活动顺序

    1、 进度管理计划

    2、 活动清单

    3、 活动属性

    4、 里程碑清单

    5、 事业环境因素

    6、 组织过程资产

    7、 项目范围说明书

    1、 前导图法

    2、 箭线图法

    3、 确定信赖关系

    4、 提前量与滞后量

    1、 项目进度网络图

    2、 项目文件更新

    4、估算活动资源

    1、 进度管理计划

    2、 活动清单

    3、 活动属性

    4、 资源日历

    5、 风险登记册

    6、 活动成本估算

    7、 事业环境因素

    8、 组织过程资产

    1、 专家判断

    2、 备选方案分析

    3、 发布的估算数据

    4、 项目管理软件

    5、 自下而上估算

    1、 活动资源需求

    2、 资源分解结构

    3、 项目文件更新

    5、估算活动持续时间

    1、 进度管理计划

    2、 活动清单

    3、 活动属性

    4、 活动资源需求

    5、 资源日历

    6、 项目范围说明书

    7、 风险登记册

    8、 资源分解结构

    9、 事业环境因素

    10、组织过程资产

    1、 专家判断

    2、 类比估算

    3、 参数估算

    4、 三点估算

    5、 群体决策技术

    6、 储备分析

    1、 活动持续时间估算

    2、 项目文件更新

    6、制定进度计划

    1、 进度管理计划

    2、 活动清单

    3、 活动属性

    4、 项目进度网络图

    5、 活动资源需求

    6、 资源日历

    7、 活动持续时间估算

    8、 项目范围说明书

    9、 风险登记册

    10、项目人员分配

    11、资源分解结构

    12、事业环境因素

    13、组织过程资产

    1、 进度网络分析法

    2、 关键路线法

    3、 关键链法

    4、 资源优化技术

    5、 建模技术

    6、 提前量和滞后量

    7、 进度压缩

    8、 进度计划编制工具

    1、 进度基准

    2、 项目进度计划

    3、 进度数据

    4、 项目日历

    5、 项目管理计划更新

    6、 项目文件更新

    7、控制进度

    1、 项目管理计划

    2、 项目进度计划

    3、 工作绩效数据

    4、 项目日历

    5、 进度数据

    6、 组织过程资产

    1、 绩效审查

    2、 项目管理软件

    3、 资源优化技术

    4、 建模技术

    5、 提前量和滞后量

    6、 进度压缩

    7、 进度计划编制工具

    1、 工作绩效信息

    2、 进度预测

    3、 变更请求

    4、 项目管理计划更新

    5、 项目文件更新

    6、 组织过程资产更新

     

     

     

    四、项目成本管理

     

    过程名

    输入

    工具和技术

    输出

    1、制定成本管理计划(规划成本)

    1、 项目管理计划

    2、 项目章程

    3、 事业环境因素

    4、 组织过程资产

    1、 专家判断

    2、 分析技术

    3、 会议

    1、成本管理计划

    2、成本估算

     

    1、 成本管理计划

    2、 人力资源管理计划

    3、 范围基准

    4、 项目进度计划

    5、 风险登记册

    6、 组织过程资产

    7、 事业环境因素

    1、 专家判断

    2、 类比估算

    3、 参数估算

    4、 自下而上估算

    5、 三点估算

    6、 储备分析

    7、 质量成本

    8、 项目管理软件

    9、 卖方投标分析

    10、群体决策技术

    1、 活动成本估算

    2、 估算依据

    3、 项目文件更新

     

    3、成本预算(制定预算)

    1、 成本管理计划

    2、 范围基准

    3、 活动成本估算

    4、 活动依据

    5、 项目进度计划

    6、 资源日历

    7、 风险登记册

    8、 协议

    9、 组织过程资产

    1、 成本汇总

    2、 储备分析

    3、 专家判断

    4、 资金限制平衡

    5、 参数模型

    1、成本基准

    2、项目资金需求

    3、项目文件更新

    4、成本控制

    1、 项目管理计划

    2、 项目资金需求

    3、 工作绩效数据

    4、 组织过程资产

    1、 挣值管理

    2、 预测

    3、 完工尚需绩效指数

    4、 绩效审查

    5、 项目管理软件(PM软件)

    6、 储备分析

    1、 工作绩效信息

    2、 成本预测

    3、 变更请求

    4、 项目文件更新

    5、 组织过程资产更新

    6、 项目管理计划更新

     

     

     

     

    五、项目质量管理

    过程名

    输入

    工具和技术

    输出

    1、规划质量管理

     

    1、 项目管理计划

    2、 干系人登记册

    3、 风险登记册

    4、 需求文件

    5、 事业环境因素

    6、 组织过程资产

    1、 成本效益分析

    2、 质量成本法

    3、 七种基本质量工具

    4、 标杆对照

    5、 实验设计

    6、 统计抽样

    7、 其他质量管理工具

    8、 会议

    1、 质量管理计划

    2、 过程改进计划

    3、 质量测量指标

    4、 质量核对单

    5、 项目文件更新

    2、实施质量保证

    1、 质量管理计划

    2、 过程改进计划

    3、 质量测量指标

    4、 质量控制测量结果

    5、 项目文件

    1、 质量审计

    2、 过程分析

    3、 质量管理与控制工具

    1、 变更请求

    2、 项目管理计划更新

    3、 项目文件更新

    4、 组织过程资产更新

    3、质量控制(控制质量)

    1、 项目管理计划

    2、 质量测量指标

    3、 质量核对单

    4、 单工作绩效数据

    5、 批准的变更请求

    6、 可交付成果

    7、 项目文件

    8、 组织过程资产

    1、 七种基本质量工具

    2、 统计抽样

    3、 检查

    4、 审查已批准的变更请求

    1、 质量控制测量结果

    2、 确认的变更

    3、 核实的可交付成果

    4、 工作绩效信息

    5、 变更请求

    6、 项目文件更新

    7、 项目管理计划更新

    8、 组织过程资产更新

     

     

     

    六、项目人力资源管理

     

    过程名称

    输入

    工具和技术

    输出

    1、编写人力资源计划(规划人力资源管理)

    1、 项目管理计划

    2、 活动资源需求

    3、 事业环境因素

    4、 组织过程资产

    1、 组织结构图和职位描述

    2、 人际交住

    3、 组织理论

    4、 专家判断

    5、 会议

    1、人力资源管理计划

    2、组建项目团队

    1、 人力资源管理计划

    2、 事业环境因素

    3、 组织过程资产

    1、 事先分派

    2、 谈判

    3、 招募

    4、 虚拟团队

    5、 多维决策分析

    1、 项目人员分配表

    2、 资源日历

    3、 项目管理计划更新

    3、建设项目团队

    1、 人力资源计划

    2、 项目人员分配表

    3、 资源日历

    1、 人际关系技能

    2、 培训

    3、 团队建设活动

    4、 基本规则

    5、 集中办公

    6、 认可与奖励

    7、 人事测评工具

    1、 团队绩效评估

    2、 事业环境因素更新

    4、管理项目团队

    1、 人力资源管理计划

    2、 项目人员分配表

    3、 团队绩效评估

    4、 问题日志

    5、 绩效报告

    6、 组织过程资产

    1、 观察和交谈

    2、 项目绩效评估

    3、 冲突管理

    4、 人际关系技能

    1、 变更请求

    2、 项目管理计划更新

    3、 项目文件更新

    4、 事业环境因素更新

    5、 组织过程资产更新

     

     

     

    七、项目沟通管理

     

    过程名称

    输入

    工具和技术

    输出

    1、制订沟通管理计划(规划沟通管理)

    1、 项目管理计划

    2、 干系人登记册

    3、 事业环境因素

    4、 组织过程资产

    1、 分析沟通需求

    2、 信息传递方法的选择

    1、 项目沟通管理计划

    2、 其他文档的更新

    2、管理沟通

     

    1、 项目沟通管理计划

    2、 工作绩效报告

    3、 组织过程资产

    4、 事业环境因素

    1、 沟通渠道的选择

    2、 信息传递方式的选择

    3、 信息管理系统

    4、 绩效报告

    1、 项目沟通

    2、 项目管理计划更新

    3、 其他项目计划更新

    4、 组织过程资产更新

    3、控制沟通

    1、 项目管理计划

    2、 项目沟通

    3、 问题日志

    4、 工作绩效数据

    5、 组织过程资产

    1、 信息管理系统

    2、 专家判断

    3、 会议

     

    1、 工作绩效信息

    2、 变更请求

    3、 项目管理计划更新

    4、 其他项目计划更新

    5、 组织过程资产更新

     

     

     

    八、项目采购管理

     

    过程名称

    输入

    工具和技术

    输出

    1、编制采购计划(规划采购)

    1、 项目管理计划

    2、 需求文档

    3、 风险登记册

    4、 活动资源要求

    5、 项目进度

    6、 活动成本估算

    7、 干系人登记册

    8、 事业环境因素

    9、 组织过程资产

    1、 自制外购分析

    2、 专家判断

    3、 市场调研

    4、 会议

    1、 采购管理计划

    2、 采购工作说明书

    3、 采购文件

    4、 供方选择标准

    5、 自制外购决策

    6、 变更申请

    7、 项目文件更新

    2、实施采购

    1、 采购管理计划

    2、 采购文件

    3、 供方选择标准

    4、 卖方建议书

    5、 项目文件

    6、 自制外购决策

    7、 采购工作说明书

    8、 组织过程资产

    1、 投标人会议

    2、 建议书评价技术

    3、 独立估算

    4、 专家判断

    5、 刊登广告

    6、 分析技术

    7、 采购谈判

    1、 选择的卖方

    2、 合同

    3、 资源日历

    4、 变更请求

    5、 项目管理计划更新

    6、 项目文件更新

    3、控制采购

    1、 项目管理计划

    2、 采购文件

    3、 合同

    4、 批准的变更请求

    5、 工作绩效报告

    6、 工作绩效数据

    1、 合同变更控制系统

    2、 检查与审计

    3、 采购绩效审查

    4、 报告绩效

    5、 支付系统

    6、 索赔管理

    7、 记录管理系统

    1、 工作绩效信息

    2、 变更请求

    3、 项目管理计划更新

    4、 项目文件更新

    5、 组织过程资产更新

    4、结束采购

    1、 合同

    2、 合同收尾程序

    3、 项目管理计划

    4、 采购文件

    1、 采购审计

    2、 采购谈判

    3、 记录管理系统

    1、 合同收尾

    2、 组织过程资产更新

     

     

    九、项目风险管理

     

    过程名称

    输入

    工具和技术

    输出

    1、规划风险管理

    1、 项目管理计划

    2、 项目章程

    3、 干系人登记册

    4、 事业环境因素

    5、 组织过程资产

    1、 分析技术

    2、 专家判断

    3、 会议

    1、风险管理计划

    2、识别风险

    1、 风险管理计划

    2、 成本管理计划

    3、 进度管理计划

    4、 质量管理计划

    5、 人力资源管理计划

    6、 范围基准

    7、 活动成本估算

    8、 活动持续时间估算

    9、 干系人登记册

    10、项目文件

    11、采购文件

    12、事业环境因素

    13、组织过程资产

    1、 文档审查

    2、 信息收集技术

    3、 核对单分析

    4、 假设分析

    5、 图解分析

    6、 SWOT分析

    7、 专家判断

     

    1、 风险登记册

    3、实施定性风险分析

    1、 风险管理计划

    2、 范围基准

    3、 风险登记册

    4、 事业环境因素

    5、 组织过程资产

    1、 风险概率和影响评价

    2、 概率和影响矩阵

    3、 风险数据质量评估

    4、 风险种类

    5、 风险紧急度评估

    6、 专家判断

    1、 风险登记册更新

    2、 假设条件日志更新

    4、实施定量风险分析

    1、 风险管理计划

    2、 成本管理计划

    3、 进度管理计划

    4、 风险登记册

    5、 事业环境因素

    6、 组织过程资产

    1、 数据收集和表示技术

    2、 定量分析和建模技术

    3、 专家判断

    1、项目的概率分布

    2、实现成本和实现目

    标的概率

    3、量化风险优先级清单

    4、定量风险结果的趋势

    5、规划风险应对

    1、 风险管理计划

    2、 风险登记册

    1、 消极风险或威胁的应对策略

    2、 积极风险或机会的应对策略

    3、 应急响应策略

    4、 专家判断

    1、项目管理计划更新

    2、项目文件更新

    6、控制风险

    1、 项目管理计划

    2、 风险登记册

    3、 工作绩效数据

    4、 工作绩效报告

    1、 风险再评估

    2、 风险审计

    3、 偏差和趋势分析

    4、 技术绩效测量

    5、 储备分析。6、会议

    1、 工作绩效信息

    2、 变更请求

    3、 项目管理计划更新

    4、 项目文件更新

    5、 组织过程资产更新

    十、项目干系人管理

    过程名称

    输入

    工具和技术

    输出

    1、识别干系人

     

    1、 项目章程

    2、 采购文件

    3、 事业环境因素

    4、 组织过程资产

    1、 会议

    2、 专家判断

    3、 干系人分析

    1、干系人登记册

    2、编制干系人管理计划(规划干系人)

    1、 项目管理计划

    2、 干系人登记册

    3、 事业环境因素

    4、 组织过程资产

    1、 会议

    2、 专家判断

    3、 分析技术

    1、 干系人管理计划

    2、 项目文件更新

    3、管理干系人参与(管理干系人)

    1、 干系人管理计划

    2、 沟通管理计划

    3、 变更日志

    4、 组织过程资产

    1、 沟通方法

    2、 人际关系技能

    3、 管理技能

    1、 问题日志

    2、 请求变更

    3、 项目管理计划更新

    4、 项目文件更新

    5、 组织过程资产更新

    4、控制干系人参与

    1、 项目管理计划

    2、 问题日志

    3、 工作绩效数据

    4、 项目文件

    1、 信息管理系统

    2、 专家判断

    3、 会议

    1、 工作绩效信息

    2、 纠正措施

    3、 变更请求

    4、 项目管理计划更新

    5、 组织过程资产更新

    6、 项目文件更新

     

    展开全文
  • 【C语言答案】第二次练习--输入输出条件判断

    千次阅读 多人点赞 2020-02-05 00:06:06
    使用软件是Devc++5.11。 A. C语言_ex02_01 运加粗样式行时间限制: 1000 运行内存限制: 65536 题目描述 输入只有一行,依次为整数a、操作符op、和整数b,a、op、b中间有一个空格分隔。其中-10000<a,b<10000...

    以下题目是由老师布置的《 谭浩强C程序设计(第四版)》的oj练习题,感谢老师的辛苦付出~
    使用软件是Devc++5.11。

    抄了作业记得点个赞谢谢!!网课也要加油学a


    一共有五道题~~~


    A. C语言_ex02_01

    加粗样式行时间限制: 1000 运行内存限制: 65536

    题目描述
    输入只有一行,依次为整数a、操作符op、和整数b,a、op、b中间有一个空格分隔。其中-10000<a,b<10000,操作符op为“+”、“-”、“*”、“/”、和“%”之一。

    输出也只有一行,为a、b两个数通过op的计算结果。比如,输入为“1 + 2”,则计算1和2的和并输出“1 + 2 = 3”。
    注意:当操作符op为“/”或“%”,且b为0时,算式无效,此时,程序输出一个单词:Invalid

    输入样例
    1 + 2
    输出样例
    1 + 2 = 3

    注意:符号与数之间有一个空格

    #include<stdio.h>
    
    int main()
    {
    	int a,b;
    	char op;
    	scanf("%d %c %d",&a,&op,&b);//scanf才用加这个 &
    	if (op=='+')//两个等于号是=,一个等于号是赋值 
    	printf ("%d + %d = %d",a,b,a+b);
    	if (op=='*')
    	printf("%d * %d = %d",a,b,a*b) ;
    	if (op=='-')
    	printf("%d - %d = %d",a,b,a-b) ;
    	if (op=='/')
    	{ 
    	if (b==0)
    	printf("Invalid") ;
    	else printf("%d / %d = %d",a,b,a/b);
    	} //两个if要用大括号 
    	if (op=='%')
    	{if (b==0)
    	printf("Invalid") ;
    	else printf("%d %% %d = %d",a,b,a%b);//百分号要用两个表示 
    	} 
    	
    }
    
    

    B. C语言_ex02_02

    运行时间限制: 1000 运行内存限制: 65536

    题目描述
    输入为两个用空格分隔的正整数year和month,它们分别代表年份和月份。输入保证合法,用int型存储即可。
    输出为year年month月的天数。

    输入样例
    2018 3
    输出样例
    31

    要先知道怎么判断闰年,能被4但是不能被100整除。和能被400整除的年份是闰年。

    #include<stdio.h>
    
    int main()
    {
    	int year, month;		//能被四不能被100整除的是闰年、能被400整除的是闰年。
    	scanf("%d %d",&year,&month);
    	
    //	if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
    //		printf("31");//也可以这样写哦,我自己想练一下switch的用法 
    
    	switch(month)
    	{
    		case 1:;
    		case 3:;
    		case 5:;
    		case 7:;
    		case 8:;
    		case 10:;
    		case 12:	printf("31");
    		default:  break;
    	}
    
    	switch(month)
    	{
    		case 4:;
    		case 6:;
    		case 9:;
    		case 11:	printf("30");
    		default:
             break;
    	}
    	if(month==2)				//如果他是二月份再判断
    	{
    		if(year%4==0&&year%100!=0)//是闰年的一种情况(能被四不能被100整除)
    			printf("29");
    			else	
    		if(year%400==0)			//另一种情况(能被400整除 ) 
    			printf("29");	
    //if((year%4==0&&year%100!=0)||(year%400==0))
    //	printf("29");
    		else 
    			printf("28");
    	}
    	return 0;  
    }
    

    C. C语言_ex02_03

    运行时间限制: 1000 运行内存限制: 65536

    题目描述
    输入只有一行,为用空格分隔的5个整数,这5个整数均大于-10000,小于10000。
    输出为这5个数的最大值。

    输入样例
    2 4 6 7 8
    输出样例
    8

    #include<stdio.h>
    int main()
    {
    int a,b,c,d,e,max;
    scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
    max=a;
    if(max<b)
    max=b;
    if(max<c)
    max=c;
    if(max<d)
    max=d;
    if(max<e)
    max=e;
    printf("%d",max);
    return 0;
    }
    //就是一个个比过去的!
    

    D. C语言_ex02_04

    运行时间限制: 1000 运行内存限制: 65536

    题目描述(前面一堆废话…)
    摄氏温度(Celsius temperature)一种使用广泛的温度。历史上它是摄氏温标所定义的温度。现在摄氏温标已废弃不用,摄氏温度有了新的定义。但在数值上,它与过去人们习惯使用的摄氏温标温度很相近。摄氏温度的规定 把在标准大气压下冰水混合物的温度定为0摄氏度,沸水的温度定为100摄氏度,0摄氏度和100摄氏度中间分为100个等分,每个等分代表1摄氏度。
    摄氏温标是A.摄尔修斯在1742年首先提出的一种经验温标,过去曾广泛使用过。摄氏温标以水沸点(标准大气压下水和水蒸气之间的平衡温度)为100度和冰点(标准大气压下冰和被空气饱和的水之间的平衡温度)为零度作为温标的两个固定点。摄氏温标采用玻璃汞温度计作为内插仪器,假定温度和汞柱的高度成正比,即把水沸点与冰点之间的汞柱的高度差等分为100格,1格对应于1度。随着测温技术的发展,人们早就不使用玻璃汞温度计作为定义温标的内插仪器了。但是后来仍有人把水沸点为 100度、冰点为零度的温标都称为摄氏温标。1954年第10届国际计量大会决定采用水三相点一个固定点来定义温度的单位,冰点已不再是温标的定义固定点了。因此,“摄氏温标”这一术语也就不应再继续使用了。
    华氏度(Fahrenheit)是用来计量温度的单位,符号℉。包括我国在内的世界上绝大多数国家都使用摄氏度;世界上仅存5个国家使用华氏度,包括巴哈马、伯利兹、英属开曼群岛、帕劳、美利坚合众国及其他附属领土(波多黎各、关岛、美属维京群岛)。
    华氏度(°F)是温度的一种度量单位,以其发明者德国人华伦海特(Gabriel D. Fahrenheit,1686—1736)命名的。1714年他发现液体金属水银比酒精更适宜制造温度计,以水银为测温介质,发明了玻璃水银温度计,选取氯化铵和冰水的混合物的冰点温度为温度计的零度,人体温度为温度计的100度。在标准大气压下,冰的熔点为32℉,水的沸点为212℉,中间有180等分,每等分为华氏1度,记作“1℉”。
    “华氏温标”是经验温标之一。在美国的日常生活中,多采用这种温标,用字母“℉”表示。
    摄氏温度(℃)和华氏温度(℉)之间的换算关系为:
    华氏度=摄氏度×1.8+32 或 华氏度=摄氏度×9/5+32
    摄氏度=(华氏度-32)÷1.8
    现请你写一段摄氏温度与华氏温度转换的程序。
    输入格式
    共一样,为一个浮点数f和一个字符c,两者之间由一个空格分隔。其中-10000<f<10000,c只可能是”C”或”F”。
    输出格式
    只有一行,如果输入的温度低于零下273.15摄氏度时,直接输出Invalid。否则输出该温度。要求,如果输入的是摄氏度则转换为华氏度,如果输入的为华氏度,转换为摄氏度。数值保留2位小数,同时在数值后输出温度单位(”C”或”F”)。具体格式见输出样例。

    输入样例
    0 C
    输出样例
    32.00 F

    注意:单位前边有一个空格

    #include<stdio.h>
    int main()
    {
    	float f,g;
    	char c,d;
    	scanf("%f %c",&f,&c);
    	
    	if(c=='C')
    	{
    		if(f+273.15<0)
    		{
    			printf("Invalid");
    			return 0;//它写在这里,让程序提前结束,最后那里写不写都行。
    		}
    		else
    		{
    			d='F';
    			g=f*1.8+32;
    			
    		}
    	}
    	if(c=='F')
    	{
    			g=(f-32)/1.8;
    			d='C';
    			
    			if(g+273.15<0)
    			{
    				printf("Invalid");
    				return 0;
    			}	
    	}
    	
    	
    	printf("%.2f %c",g,d);
     } 
    

    E. C语言_ex02_05

    运行时间限制: 1000 运行内存限制: 65536

    题目描述
    输入只有一行,为三个用空格分隔的浮点数a,b,c(0<a,b,c<100)
    输出也只有一行,如果 a - b 等于c ,则输出yes,否则输出no。

    输入样例
    3.4 2.2 1.3
    输出样例
    no

    #include<stdio.h>
    int main()
    {
    	float a,b,c;
    	scanf("%f %f %f",&a,&b,&c);
    	if(a-b-c<1e-1&&a-b-c>-1e-1)
    	printf("yes");
    	else
    		printf("no");
    	
     } 
    
    展开全文
  • 输入输出系统

    千次阅读 2018-11-18 18:40:20
    输入输出系统的发展概况 (一)分散连接 早期的计算机,计算机数量少,应用少,外部设备少,外部设备和主机之间的连接采用分散连接的方式,CPU 和 I/O设备 串行 工作,采用程序查询方式。也就是每个设备都有专门的...

    输入输出系统的发展概况

    (一)分散连接

    早期的计算机,计算机数量少,应用少,外部设备少,外部设备和主机之间的连接采用分散连接的方式,CPU 和 I/O设备 串行 工作,采用程序查询方式。也就是每个设备都有专门的控制线路,这些控制线路甚至和CPU的控制线路设计在一起,紧密耦合,这时候,如果增减外部设备非常难,但是由于当时计算机和外部设备数量少,这样设计还是值得的。这时,外部设备和主机之间的连接主要还是采用程序查询的方式,在这种方式中,CPU的工作和IO工作是串行执行的,IO在进行数据的输入和输出的时候,CPU必须运行相应的程序或处于停等状态。

    (二)接口模块和DMA阶段

    当外部设备越来越多,分散连接的方式已经不适应外部设备的发展、计算机技术的发展以及计算机领域的扩展,这种情况下就出现了IO接口和DMA控制器。由IO接口、DMA控制器和主机相互配合完成数据的输入、输出操作,连接方式也发生了变化,采用了总线的方式进行连接,IO设备通过接口连接在总线上,一个总线可以连接多个设备,总线另外一端和主机相联,这种情况下,主机和IO设备进行传输的传输控制方式也发生了变化,要求CPU和IO之间并行进行工作,所以出现了信息传输方式,即中断和DMA。

    (三)具有通道结构的IO阶段

    在中断和DMA两种方式的信息传输过程中,或者信息完成之后,仍需要CPU参与部分信息传输的处理工作。为了使CPU工作和IO工作能估并行起来,或者是输入输出的数据输入输出的管理控制,尽可能的从主机中独立出来。就出现了具有通道结构的IO阶段。

    通道可以看作是一种简单的处理器 ,或者是一个小型的,功能更强的DMA控制器,他能够执行通道程序,通道有自己的指令系统,通过执行通道程序,可以控制连接在通道上的IO设备和主机之间直接进行传输。

    (四)具有IO处理机阶段

    IO处理机,可以是专用的处理机,在大型计算机中,我们可以使用现在的微处理器直接作为IO处理机来用,控制IO设备的工作,或者在有些大型计算机中,直接使用和主机中处理器完全相同的处理器来作为IO处理器,这时,IO处理器功能非常强大,甚至在没有IO设备的时候,可以主机处理器进行使用完成相应的任务。

    输入输出系统的组成

    (一)IO软件

    1、IO指令: CPU指令的一部分,CPU通过这些指令控制IO设备协调工作。
    在这里插入图片描述

    操作码:表示这样的指令是IO指令

    命令码:相当于CPU指令中普通指令的操作码,指出了要对IO设备做怎样的操作,如:对IO设备进行查询,输入,输出,以及其他的控制

    设备码:给出的是IO设备的编码,也就是IO设备的地址,或者是IO设备中某一个寄存器的地址,这些寄存器叫做IO端口。

    2、通道指令: 通道自身的指令

    通道自身的指令,通道是一种小型的MDA处理机,能够实现IO设备和主机之间直接进行信息传送,通道有自己的控制器,有的通道还有自己的存储器,通道能够执行由通道指令组成的通道程序,通道指令就是通道自身的指令,通常情况下,编程人员,在应用程序中,为了调用外部设备,使得外部设备能够工作,应用程序中需要增加广义IO指令,广义IO指令要指出参加数据传输的IO设备,数据传输主存的首地址,传输数据的长度,传输的方向(向IO设备传输数据还是向主存传输数据),操作系统通过广义IO指令给出的参数以及要求的操作,会编写一个由通道指令组成的通道程序,并且把通道程序放在内存或者是通道自己的内存指定的位置,之后启动通道进行工作,通道拿到通道程序的首地址后,就可以执行通道程序,控制IO设备完成相应的输入输出工作,所以通道指令中的一些参数需要指出要传输成块数据的首地址,当然通道也可以传输单个字节,这时候需要指出这个字节在内存中的地址,或者是要把这个字节传输到内存中的哪一个地址,如果是一组数据,还要指定传输的字数 ,传输的方向,设备地址等,这些参数都要有通道指令指出,这些指令一般比较长,通道下面还可以带若干个子通道,子通道可以并行进行工作,每个字通道下可以连接多个设备控制器,每个设备控制器可以连接多个设备

    (二)IO硬件

    IO设备,IO接口
    IO设备通过IO接口连接在总线上,和主机完成信息交换,
    设备连接设备控制器,设备控制器连接通道,通道连接子通道。

    IO设备与主机的联系方式

    如果CPU要启动IO设备进行输入输出,那么主机和IO设备如何进行联系。

    (一)IO设备编码

    1、统一编址
    把IO设备的编址看成是内存地址的一部分,比如将内存的高位或者低位部分地址作为IO设备地址,当CPU访问内存的这部分地址的时候,就相当于是对IO设备的访问,这样CPU使用存数、取数指令对IO设备进行访问控制,我们不需要单独的IO指令,只要CPU指令的地址码落到了内存IO地址的部分,那这条指令就是对IO地址进行操作的,这种方式CPU的指令集会相对简单。如果内存地址的编址比较大的话,就可以采用统一编址的方式

    2、不统一编址(单独编址)

    在内存地址之外,专门设置一个地址空间,如内存地址空间是20位,寻址范围是1M,对外部设备进行编址时候,使用16位,即64K,为了区分一条指令是对内存进行操作,还是对IO设备进行操作,在单独编址的计算机中,输入输出指令就不能计算机系统原有的取数或者存数指令,我们要用专用的IO指令来对IO设备进行控制操作。

    (二)设备选址

    用设备选择电路识别是否被选中:把IO设备中保存的地址和CPU指令给定的地址进行比较即可。

    (三)数据传输

    1、 串行,数据一位一位进行传输,传输速度慢,但是适合远程传输
    2、 并行,同时传输多位数据,所以有多条线路,通常数据线条数为8的倍数。

    (四)联络方式

    在这里插入图片描述

    为了进行并行工作, IO设备和IO接口之间要有多条数据线组成的类似总线结构的数据线来完成数据并行的输入和输出,双方之间还要采用应答信号。

    如果IO设备要接受数据,IO接口把数据准备好以后,通过Ready信号告诉IO设备端口中的数据已经准备好了,IO设备对端口中的数据进行读取,并给出应答信号。

    如果是输入,IO设备通过IO接口将数据输入到CPU中,或者输入都主机中,IO接口当中的数据缓冲器一旦空了,会向IO设备发送Ready信号,告诉IO设备可以向IO接口中发送数据了,IO设备向IO接口发送数据,并且给出应答信号。

    IO设备与主机间连接方式

    (一)分散连接

    在这里插入图片描述
    每台设备都配有一套,控制线路和一组信号线,这种方式不便于增删设备。

    (二)总线连接

    外部设备通过接口和CPU进行连接,接口能够向外部设备传送CPU的控制命令,可以向CPU传送外部设备的状态信息,同样,接口还可以完成数据缓存,外部设备输入的数据可以先缓存在接口中,完成数据的格式转换操作,在传送给主机,或者主机中的数据在接口中进行缓存,经过格式转换处理传输给外部设备。这种方式便于增删设备。

    IO设备与主机信息传送的控制方式

    (一)程序查询方式

    这种方式中,CPU和外设采用串行方式进行工作的。
    在这里插入图片描述
    从外部设备中读取一批数据进入计算机内存的过程:首先CPU在程序中执行一条指令,这条指令就是读操作,向IO设备发出读命令,发出读命令以后,CPU开始读取IO的状态,实际上是IO接口中状态标志值,看数据是否被准备好,如果数据没有被准备好,就会执行跳转指令继续不断地读取状态判断数据是否准备好,如果状态标志显示数据已经被准备好了,这时候CPU就可以从接口中读出数据,这个数据可以是一个字节,也可以是一个字,把这些数据放到CPU的某一个寄存器中,然后把寄存器中保存的数据写入到内存指定的位置,然后判断传输是否结束,如果没有结束,CPU继续通过程序向IO设备发出读指令。

    在这里插入图片描述

    图为查询外部IO设备是否准备好数据的逻辑,一般,外部设备执行的速度很慢,CPU执行速度很快,外部设备经过一个较长的时间才能把数据准备好,然后将准备好的数据送入到IO接口中的数据缓冲,然后状态置为数据准备好了。CPU只有查询到数据准备好了才能进行数据传输。在数据准备过程中,CPU一直处于原地踏步状态,没有去执行其他指令,没有去做其他工作,这样CPU的效率非常低。

    在以上的工作方式中,内存和CPU工作过程中,必须要通过CPU,先要把数据送入到CPU的寄存器中,然后把数据送入指定的目标,这个目标可以是外部设备,也可以是内存的某一个存储单元,在这种情况下,内存—CPU—IO三者之间的连接关系可以看作是以CPU为中心,信息交换必须经过CPU,外部设备慢,CPU速度快,在数据准备过程中消耗了CPU的大量时间,造成CPU的效率非常低。

    (二)程序中断方式

    在这里插入图片描述
    中断方式过程: CPU执行主程序,在执行程序过程中碰到一个IO指令,执行这个IO执行,启动IO设备进行数据准备,发出启动设备的指令后,CPU继续执行原来的程序,外部设备接收到了启动设备的命令,接收到了输入输出操作的命令,外部设备开始进行状态准备,当外部设备准备好接收或者是输入数据以后,他就会向CPU提出一个中断请求让CPU停止对当前程序的执行,转而和IO设备进行数据交换,当数据交换完成,CPU继续执行原有的主程序。
    在这里插入图片描述
    这种方式,在设备自身准备阶段,CPU没有等待,只有到了真正进行数据传输了,由外部设备主动的发起中断请求信号,请求CPU协助完成数据的输入和输出操作。

    IO工作可以分成两个阶段,数据准备阶段和与主机交换信息阶段,在程序查询方式当中,数据准备和与主机相互交换信息两个阶段,CPU都要参与工作,程序中断方式对程序查询方式进行了改进,在IO设备和IO接口进行数据准备的时候,CPU不进行查询只有当外部设备和内存之间开始进行信息交换的时候,CPU才会暂停(中断)现行程序,为输入和输出进行服务。
    在这里插入图片描述
    这种方式中,CPU实现了和IO设备之间部分的并行工作,也就是在IO设备进行数据准备的时候,CPU还可以执行自己的程序,不需要停等。这种方式CPU可以一定程度的成数据的输入输出中解放出来。

    这种情况一定程度的对CPU进行了解放,但是不彻底,因为数据传输过程中仍然需要CPU的参与,而且要保证程序被中断掉以后,CPU返回了能正确的继续执行程序,这就需要CPU执行保存现场和恢复现场的指令,需要消耗一定的时间。如果外部设备和内存之间传输的数据数据量特别小,比如只传输1个字节,但是扔需要CPU执行很多条指令来完成现场的保护或者是恢复工作,依然会消耗CPU大量的时间。

    (三)DMA方式

    这种方式在内存和IO之间建立了直接的通路,内存和IO直接通过DMA控制器进行数据交换,在数据交换过程中也不需要CPU的参与,把CPU进一步的从数据的输入和输出中解放出来。不需要中断现行程序的执行,采用周期挪用(周期窃取),由DMA控制器直接控制外部设备和内存直接进行数据交换。

    周期挪用: 因为DMA控制主存和外设之间进行信息交换,一定要使用到总线(地址线,数据线,控制线),这些总线如果DMA利用他们进行信息交换,那CPU就要把总线的使用权让出来,让出来的时间就是一个存取周期,在这个存取周期中,如果DMA要完成IO和内存之间的数据交换,那这个存取周期,总线就交给DMA使用,同样,总线控制权也交给DMA,这种方式叫做周期挪用。
    在这里插入图片描述

    上图中,CPU执行主程序,当CPU碰到了IO指令要进行数据输入或者数据输出,CPU发出启动IO的指令,发出指令之后,CPU继续执行自己的程序,IO设备在DMA控制器的控制之下,完成数据的准备,当数据准备好以后,要进行数据传输了,由DMA控制器发出DMA占用总线请求,占用一个存取周期,利用这一个存取后期进行外部设备和IO之间的数据交换,在这一个存取周期中,CPU不能使用总线对内存进行访问,这个周期结束以后,IO设备可以继续进行准备,CPU继续去执行现行的程序,也就是这个周期结束后,总线的控制权,对内存的使用权又归还给了CPU,在这一个存取周期中,CPU虽然不能使用总线,不能访问内存,但是这个周期中CPU还是可以执行的,比如:现在处理器, 并不是CPU每执行一条指令就从内存中取出一条指令,指令是需要预取的,在指令执行之前,可能若干条指令已经被预取到CPU的执行缓冲当中了,只要这些指令不需要访存,或者是在这个存取周期中不需要访存,CPU就可以利用指令缓存中的指令或数据继续执行主程序中的指令,所以在这一个存取周期中,CPU的工作和外部设备和内存间的数据交互还是可以进行并行操作的。

    (四)三种方式的比较

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    IO设备

    在这里插入图片描述

    IO设备通过接口电路和主机进行连接,外部设备包括两大部分,设备控制器和机电磁光部分,外部设备设备通过IO接口和主机之间进行数据交换,主机通过IO接口向设备控制器传输控制命令,控制外部设备进行相相关的操作;同样,主机通过IO接口来读取外部设备的状态。
    外部设备分类:

    人机交互设备 键盘、鼠标、打印机、显示器
    计算机信息存储设备 磁盘、光盘、磁带
    机 机通信设备 调制解调器等

    A/D、D/A(模拟/数字(数字/模拟)转换器): 计算机内部使用的都是数字信号,如果计算机要对外部设备进行控制,或者是要把信号进行远程传输,需要将数字信号转换成模拟信号,在接收端,需要在把模拟信号转换成数字信号。同样,外部设备对主机的输入,可能采用的是模拟信号,主机需要将模拟信号转换成数字信号。

    终端: 终端一般由显示器和键盘组成,但不仅仅是键盘和显示器,还有一些控制机构,缓存等。一般终端不能进行单独工作,需要一些连接线和远程的主机进行连接,才能进行工作。

    IO接口

    (一)为什么要使用IO接口

    1、 实现设备的选择
    我们使用总线的方式来完成外部设备和系统主机之间的连接,外部设备要有地址,主机通过地址来确认这次数据传输是和那个设备进行数据传输。

    2、 实现数据缓冲达到速度的匹配。
    外部设备工作多样,工作速度差异也非常大,有的速度比较快,如硬盘,有的速度比较慢,如键盘,可能很长时间来能输入一个字节的数据,要通过接口实现数据缓冲,达到速度匹配的问题。

    3、 实现数据串—并格式转换。
    接口和主机之间采用并行传输,一次传输一个字节或者一个字,外部设备和接口之间可能采用串行传输,一位一位的传输,数据要在接口中完成数据的组装或者拆解,做格式转换。

    4、 实现电平转换
    主机和IO设备工作的电平不一致,通过IO接口完成电平的转换,是主机和IO设备能够协调进行工作。

    5、 传送控制命令
    CPU把控制命令传输到接口当中,由这个命令控制外部设备进行工作。

    6、 反应设备状态(忙,就绪,中断请求)
    接口总要有状态标志。

    (二)接口的功能和组成

    1、总线连接方式的 I/O 接口电路

    在这里插入图片描述
    设备选择线
    传输的是参与本次信息交换的设备的设备码或者是端口号,实际上就是设备的地址或者是端口的地址,这个地址传输给IO接口,在IO接口中进行匹配,看是否是这个接口上连接的某个设备要参与这次数据传输,这条线是单向线。
    数据线
    完成数据的输入和输出,线的条数和接口类型有关,双向线。
    命令线
    来自CPU的命令,通过命令线输入到IO接口中,命令经过缓冲和译码以后,可以控制设备进行相应的输入和输出操作。
    状态线
    单向线, 从IO接口送到IO总线,进而送到主机由主机连接外部设备的状态。

    2、接口的功能

    功能 组成
    选址功能 设备选择电路
    传送命令的功能 命令寄存器、命令译码器
    传送数据的功能 数据缓冲寄存器
    反映设备状态的功能 设备状态标记

    在这里插入图片描述
    完成触发器: 用于标记设备是否准备好,数据是否准备好,D = 1完成,D = 0未完成
    工作触发器: 用于标识外部设备共组是否忙,B = 1忙,B = 0闲
    中断请求触发器: 中断方式中,数据准备好以后主动由设备提出中断请求,因此接口中要有中断请求触发器,另外接口可能有中断请求,但是是否允许他向主机提出中断请求要看设备中断请求的重要性。因此在接口中设置了屏蔽触发器。
    屏蔽触发器: 如果屏蔽触发器 = 1 尽管设备已经完成了工作,依然不能向主机或者CPU发出中断请求。因为主机当前处理的程序的重要性比这次输入输出操作的重要性高。

    (三)IO接口组成

    在这里插入图片描述
    控制逻辑电路:控制其他四个部分按照时序进行工作等。

    左端:
    数据线:双向并行传输
    地址线:给出的是外部设备的地址,供设备选择电路使用,
    命令线:给出设备操作命令,放在命令寄存器中进行锁存,进而进行译码,并且在时序控制电路的控制下给出各个操作以及操作之间的时间关系。
    状态线:把IO接口、外部设备的状态传输给CPU。

    右侧:
    数据线:传输接口和设备之间需要传输的数据。
    命令线:来自于命令译码器和时序逻辑,控制外部设备做相应的工作。
    状态线: 外部设备状态输入,对状态标记进行置位或者复位。

    (四)IO接口类型

    分类方式 分类
    传送方式 并行接口,串行接口
    选择的灵活性 可编程接口,不可编程接口
    通用性 通用接口、专用接口
    数据传送的 控制方式 中断接口,DMA 接口

    程序查询方式

    (一)程序查询方式的流程

    单个设备
    在这里插入图片描述

    如果只有一个设备参与内存和IO之间的数据传输,在执行程序的过程中,CPU执行到一个输入输出指令,由这个输入输出指令发出启动设备的命令,相应的设备接收到这个命令之后,就进行相应的数据准备,数据准备好以后,再传输给CPU,CPU发出设备启动命令之后,开始检查设备状态标记,看IO接口中的数据是否已经准备好,设备是否已经准备好进行输入或者输出,如果准备就绪,就进行数据交换,如果没有准备就绪,CPU就处于一种踏步状态,通过循环的方式检查状态标记,知道数据准备好,开始交换数据,这个过程中我们要使用三条指令:
    1、 检查状态标记指令:测试指令
    2、 在检查设备是否准备就绪,需要一个转移指令
    3、 数据传送指令进行交换数据、数据输入输出指令或者访存指令

    多个设备
    在这里插入图片描述
    如果有多个设备都要通过程序查询方式和CPU进行数据交换, 都要通过程序查询方式和内存进行数据交换,我们需要把参与传输的这些设备按照优先级进行排序,优先级越高的设备被查询到的时间就越早。

    (二)程序查询方式的接口电路

    程序流程
    在这里插入图片描述

    首先要保存寄存器内容:因为程序查询方式要完成内存和外设的数据输入输出,需要借助CPU中的某一个寄存器对数据进行暂存,如果这个寄存器中的数据是有用的,我们要对这个寄存器中的数据进行保存,可以把他写入到某一个内存单元中,把他压入堆栈中,或者把他放入到其他寄存器中进行保存。

    设置计数器值:控制传输的数据量,这次内存和IO之间进行数据传输到底传输多大量的数据,计数值的设置有两种方式:1、如果我们要传输n个字,计数器的值就设置为n,每完成一个字的传输,将n-1,直到减到0为止,就完成了数据的传输。2、把计数器的值设置为-n,并且这个负数用补码进行表示。每传输一个字,在这种情况下,对计数器的加1,直到计数器溢出,计数器中的值变成0,数据传输结束。

    设置主存缓冲区地址:数据传输需要只要内存这个块的地址是多少。我们保存数据或者读取数据就从这个主存缓冲区的首地址开始。

    启动外部设备:让外部设备进行准备和数据传输。

    启动外部设备以后,CPU开始查询外部设备的状态或者是IO接口的状态,如果没有准备好,CPU进行原地踏步反复进行查询,知道状态标志标明数据已经准备好了,这个查询操作才会停止开始进行数据传输。

    数据传输完以后:
    修改内存地址:加一或者减一,为下次输入或者输出做准备。
    修改计数值:加一或者减一,表名还有多少数据需要传输。
    判断数据是否传输完成。

    程序员编写一个程序,要用程序查询的这种方式来完成数据输入输出,在他的应用程序中,需要嵌入以上的程序流程,由这段程序完成数据输入和输出操作,根据这个流程以及IO接口电路的基本结构,我们可以得到程序查询的接口电路:

    在这里插入图片描述
    以数据输入为例对上图进行分析:

    1、 CPU通过地址线给出外部设备的地址

    2、 设备选择电路把自己的设备地址或者是端口号和地址线上的地址进行比较,如果相同,说明启动的就是连接在这个接口电路上的设备,此时SEL信号有效。

    3、 启动命令和SEL信号都有效的前提下,对两个状态标记进行置位或者是复位。

    4、 目前是CPU发出读命令,设备还没有开始工总,因此标记D = 0表示数据还没有准备好,标记B = 1表示设备开始工作设备处于忙状态,

    5、 B标记去启动设备,设备接收到B的标记信号后以及启动命令之后,这杯开始工作,

    6、 设备把数据准备好,并且数据通过输入的数据线把他保存到DBR数据缓冲当中,这时设备工作结束。

    7、 设备通过设备状态线向接口电路送入设备工作结束信号,这个信号会修改接口电路中的两个标记,D = 1表示数据已经准备好,B = 0表示设备闲,工作已经完成。

    8、 D准备就绪信号被送出。
    在上述过程中,直到D状态为1前,CPU都在原地踏步查询D。

    9、 CPU查询到D = 1,说明数据已经准备好,并且已经放入到DBR。

    10、 CPU通过数据线对数据进行读入。

    程序中断方式

    CPU执行程序的过程中,如果发生意外事件或者是特殊事件,CPU要中断当前程序的处理执行,转而处理特殊事件或者是异常事件,通过执行中断服务程序的方式进行处理,处理结束之后,要返回到被中断的程序的断点继续执行原来的程序。
    在这里插入图片描述

    (一)IO中断的产生

    以打印机为例,CPU 与打印机部分并行工作:
    在这里插入图片描述

    (二)程序中断方式的接口电路

    1、配置中断请求触发器和中断屏蔽触发器

    由外部设备对中断请求标志进行设置值,表明有中断请求,这个中断请求标志能否变成中断请求信号向CPU发出中断请求,还需要看这个中断请求标志是否会被屏蔽掉,所以需要一个中断屏蔽触发器,因为有时计算机正在执行的程序他的重要性高。
    在这里插入图片描述

    排队器

    在同一个时刻,向CPU发出中断请求的可能有多个设备,这些设备的优先级是不一样的。经过排队之后,只有优先级最高的设备提出的中断请求会被响应。

    排队器有硬件和软件两种实现方式,这里简述硬件排队方式实现。硬件实现电路在 CPU 内或在接口电路中。

    在这里插入图片描述
    设备 1#、2#、3#、4# 优先级按 降序排列,INTRi = 1 为有请求, 即 ! INTRi = 0,最终输出的INIP只有一个是高电平,其他的都是低电平,高电平代表目前要相应的优先级最该的IO设备

    中断向量地址形成部件

    需要执行中断程序,必须知道中断服务程序的入口地址。也就是中断服务程序在内存中的起始地址。
    入口地址的产生方式也有两种,硬件方式与软件方式,这里简述硬件方式。硬件方式由 硬件 产生 向量地址,再由 向量地址 找到 入口地址。

    在这里插入图片描述

    中断号:中断编号,如8086中支持256个中断,这256个中断被编号成0-255
    中断向量:中断服务程序的入口地址,段地址 + 偏移量,以及执行中断服务程序的状态信息。
    中断服务程序的入口地址:可以由中断地址生成
    向量地址:中断向量保存的内存单元的地址。

    程序中断方式接口电路的基本组成
    在这里插入图片描述

    (三)IO中断处理过程

    1、CPU响应中断的条件和时间
    条件:
    允许中断触发器 EINT = 1。
    用 开中断 指令将 EINT 置 “1”,用 关中断 指令将 EINT 置“ 0” 或硬件 自动复位。

    时间:
    当 D = 1(随机)且 MASK = 0 时。
    在每条指令执行阶段的结束前。
    CPU 发 中断查询信号(将 INTR 置“1”)。

    2、IO中断处理过程

    以数据输入为例:

    在这里插入图片描述
    当CPU在执行程序的时候,遇到一个输入指令,要求把指令的外部设备把数据输入到主机中。

    1、 CPU通过这条指令在数据线上给出设备的地址,

    2、 设备地址送到接口电路中后,利用设备选择电路和设备地址进行比较,如果相同,那这个接口和相对应的设备就被选中,SEL信号有效,接口电路开始工作。设备被选择的信号。

    3、 CPU送来启动命令或者是对接口和设备的控制命令,这个命令在接口中进行译码。

    4、 启动命令和SEL信号同时有效 ,触发器B = 1用于启动设备,并且表示设备开始工作设备忙,触发器D = 0表示数据还没有准备好,

    5、 接口工作结束以后,将数据送入到接口中的数据缓冲区DBR。B = 0表示接口工作完成处于闲状态,D = 1表示数据已经准备好。

    6、 如果接口的中断请求没有被屏蔽,发出中断请求,经过排队器进行排队,排队器的输出信号只有一个是1。

    7、 CPU发出中断响应信号,形成向量地址,向量地址(包含设备号等信息)通过数据线传输给CPU,传给PC,PC通过这个地址取出中断程序的入口地址。

    (四)中断服务程序流程

    服务流程

    保护现场————中断服务(对不同的 I/O 设备具有不同内容的设备服务)————恢复现场(出栈指令)————中断返回(中断返回指令)

    程序断点保护:当前PC中保存的地址的值。有些不能读取的状态也需要进行保护,直接通过硬件完成,这个称为中断隐指令,并不是一条指令。

    寄存器内容的保护:中断服务程序可能会利用到CPU中的某些寄存器,这些寄存器之前的值也需要进行保护,通过进栈指令进行保护

    单重中断
    CPU在执行中断服务程序的过程中,如果有了新的中断请求,不管新的中断请求的优先级有多高,都不能中断现行的中断服务程序。
    在这里插入图片描述
    多重中断
    CPU在执行中断服务程序的过程中,允许级别级别更高的中断源中断现行的中断服务程序。
    在这里插入图片描述

    (五)中断方式,主程序和服务程序抢占 CPU 示意图

    在这里插入图片描述
    宏观 上 CPU 和 I/O 并行 工作,微观 上 CPU 中断现行程序 为 I/O 服务。

    DMA方式

    (一)DMA方式的特点

    1、DMA 和程序中断方式的数据通路比较
    在这里插入图片描述
    2、DMA与主存交换数据的三种方式
    (1)停止CPU访问主存

    在这里插入图片描述

    控制简单,CPU放弃总线和内存使用权,将使用权交给DMA接口。适合大量数据进行传输。

    问题:数据传输过程中,如果CPU的指令缓冲器中有指令或者是已经将指令或者数据加载进了cache,CPU可以继续执行指令。但是当没有指令和数据了,CPU将会保持当前的状态。

    这种方式不能充分发挥CPU利用率。因为当一块数据传输给主存的过程中,数据是一个字一个字的在外部设备和主存之间进行传输, 传输的间隔可能会比较大,这个时间会超过一个主存周期。在传输间隔这段时间,虽然DMA接口没有直接使用主存,但是依然占用主存的访问权,CPU这段时间不能访问主存执行程序。

    (2)周期挪用(周期窃取)
    在这里插入图片描述

    这里的周期指的是访存周期,如果DMA接口准备好了数据传输,就申请总线的使用权,占用一个或者是几个内存访问周期,完成数据的传输,在数据传输的间隔或者是数据准备阶段,DMA接口放弃对内存的使用和对总线的占用。
    DMA访问主存有三种可能:
    CPU此时不访存
    CPU正在访存,正处于某一个访存周期的中间阶段,DMA等待
    CPU和DMA同时请求访存,这种情况下,DMA优先的,CPU要放弃对内存和总线的控制权

    (3)DMA和CPU交替访问
    在这里插入图片描述

    在这里插入图片描述
    由于在固定的时间点,存储器和IO总线使用权是固定的,就不需要DMA提出DMA申请,建立对总线和内存的控制权和使用权,速度比较快。

    (二)DMA接口的功能和组成

    功能

    (1) 向 CPU 申请 DMA 传送
    (2) 处理总线 控制权的转交
    (3) 管理 系统总线、控制 数据传送
    (4) 确定 数据传送的 首地址和长度,修正 传送过程中的数据 地址 和 长度
    (5) DMA 传送结束时,给出操作完成信号
    组成
    在这里插入图片描述
    AR:地址寄存器,由CPU给出,存放下一个数据将要放在内存中的那个位置,如果数据的存放是由低地址向高地址,每存入一次将AR + 1

    WC:存放的是将要放入CPU中的数据的字长,最开始存放-n,每次存入一次,WC + 1

    BR:数据缓冲器,外部设备的数据或者是存储单元中输出的数据,要暂在接口的数据缓冲器中。

    DAR:设备地址寄存器
    (1) 供设备选择电路使用,判断这次访问的设备是不是这个接口中当前连接的设备,是否由这个DMA接口进行管理。
    (2) 对硬盘进行访问的时候,这个DAR中还可以用于保存柱面号,磁道号,扇区号。

    DMA控制逻辑:控制接口内部协调工作,控制在给定的时序发出给定的信号,如给CPU发出DMA请求。向主存发出读写信号。外部设备要向DMA进行数据传输,外部设备要向DMA控制器发出请求信号,DMA控制器向设备发出控制信号。给CPU发出总线占用请求信号,CPU发出应答信号。
    中断机构:用于数据传输完以后,对后续工作进行处理的。如WC = 0表示传输结束,如果等于0,就会向中断机构发送信号,给终端机构的中断请求触发器状态置为1,当一条输入指令执行完成后,由中断机构发信息给CPU,让CPU做完成后的处理。

    (三)DMA工作过程

    预处理、数据传送、后处理
    在这里插入图片描述

    1、预处理
    (1)通知 DMA 控制逻辑传送方向(入/出)
    (2)设备地址 DMA 的 DAR
    (3)主存地址 DMA 的 AR
    (4)传送字数 DMA 的 WC
    2、数据传送
    在这里插入图片描述

    允许传送:能否占用内存和总线的使用权,如果CPU正在使用总线和内存(一个存储周期未结束),DMA等待。

    数据传输过程如下:

    数据输入:
    在这里插入图片描述1、 将数据输入到BR

    2、 通知设备请求信号DREQ告诉DMA控制逻辑数据已经准备好了。

    3、 DMA控制逻辑通过总线向CPU提出总线和主存占用请求

    4、 CPU在允许的时候给出应答,此时CPU会放弃总线和主存的占用权,总线和主存由DMA接口进行控制。

    5、 要进行数据传输,就要给出主存的地址,此时由AR给出要将数据写入的内存中的地址,使得系统总线中地址总线是有效的

    6、 由设备控制器给出设备应答信号DACK,告诉设备已经开始信息传输。

    7、 对内存的读写控制信号由DMA控制逻辑给出,数据由 BR发出通过数据线传送给主存,每传输一个数据,AR + 1, WC + 1.

    8、 通过溢出信号判断数据是否传送完成,如果溢出,会将溢出信号传送给中断机构,使得中断请求触发器置1,参数中断排队,发出中断请求信号给CPU,使得CPU去做中断后处理。没有溢出,即没有传输完会继续进行传输,下次传输,设备继续将数据放入BR中。

    数据输出:

    在这里插入图片描述
    1、 将BR中的数据送入到设备中,此时BR中数据为空。

    2、 由DREQ发出信号通知设备控制器,BR已经空了,可以用于接收下一个数据了。

    3、 DMA控制逻辑通过总线向CPU提出总线和主存占用请求

    4、 CPU在允许的时候给出应答,此时CPU会放弃总线和主存的占用权,总线和主存由DMA接口进行控制。允许下一次的数据输出

    5、 要进行数据传输,就要给出主存的地址,此时由AR给出要将数据写入的内存中的地址,使得系统总线中地址总线是有效的

    6、 由设备控制器给出设备应答信号DACK,告诉设备已经进行了新的数据传输。

    7、 次数内存中的数据通过数据线再次写入到BR中,每传输一个数据,AR + 1, WC + 1。

    8、 通过溢出信号判断数据是否传送完成,如果溢出,会将溢出信号传送给中断机构,使得中断请求触发器置1,参数中断排队,发出中断请求信号给CPU,使得CPU去做中断后处理。没有溢出,即没有传输完会继续进行传输,下次传输,设备继续将数据放入BR中。

    3、后处理
    由中断服务程序完成:
    (1)校验送入主存的数是否正确
    (2)是否继续用 DMA
    (3)测试传送过程是否正确,错则转诊断程序

    (四)DMA接口和系统连接方式

    1、具有公共请求线的 DMA 请求

    在这里插入图片描述
    2、独立的 DMA 请求
    在这里插入图片描述

    (五)DMA 方式与程序中断方式的比较

    中断方式 DMA 方式
    数据传送 程序 硬件
    响应时间 指令执行结束 存取周期结束
    处理异常情况 不能
    中断请求 传送数据 后处理
    优先级

    (五)DMA接口类型

    (一)选择型

    在 物理上 连接 多个 设备 ,在 逻辑上 只允许连接 一个 设备

    在这里插入图片描述
    从物理上说一个DMA接口可以连接多个设备,但是在数据准备和数据传送的整个过程中,在逻辑上实际上这个接口只能连接一个设备

    (二)多路型

    在 物理上 连接 多个 设备 ,在 逻辑上 允许连接 多个 设备同时工作

    在这里插入图片描述
    多路型 DMA 接口的工作原理:

    在这里插入图片描述

    展开全文
  • Java输入输出

    千次阅读 2017-11-02 11:54:07
    Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。   ...
  • MSP432输入输出模块

    千次阅读 2019-06-30 19:47:10
    第6章MsP432微控制器输入输出模块 单片机中的输入输出模块是供信号输入、输出所用的模块化单元。MsP432单片机的片内输入输出模块非常丰富,典型的输入输出模块有:通用O端口、模/数转换模块、比较器E  定时器。...
  • 本阶段是整个软件开发的开始阶段,输入可以是为了提高工作效率的某个好的想法或者是公司领导为了帮助管理发出的命令。输出就是业务需求文档,英文称为Business Requirement Document。这个文档的文字描述的抽象层次...
  • 模拟量输入输出模块的模拟量是表示在一定范围内连续变化的任意取值,跟数字量是相对立的一个状态表示。通常模拟量用于采集和表示事物的电压电流或者频率等参数。驱动硬件输出和相关数据通路,按照运行方式选择当前的...
  • C++的标准输入输出

    千次阅读 2018-01-18 21:54:11
    转载自:...从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件。程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件
  • springboot实现文件的输入输出

    千次阅读 2019-05-19 13:53:58
    这里主要是实现excel,CSV文件的输入输出及PDF的输入输出。 1,首先是excel,使用poi实现导入导出 POI详细介绍参考:https://www.cnblogs.com/huajiezh/p/5467821.html 常识: xlsx和xls都是excel文件名扩展名,xls...
  • 中断与输入输出

    千次阅读 2011-06-19 13:34:00
    输入/输出系统1、主机与外设的连接1.1、输入输出接口I/O接口是主存和外设之间的交接界面,通过接口可以实现主机和外设之间的信息交换主机和外设之间需要交换的信息:数据信息:这些信息可以是通过输入设备送到计算机...
  • 第 11 章 输入输出系统 基本知识点:I/O 系统的概念和组成;I/O 设备与主机的联系方式;I/O 接口的功能和基本结构;I/O 端口及其编址;I/O 地址空间及其编码;四种 I/O 控制方式,包括程序查询方式、程序中断方式、...
  • c++中输入输出流详解

    千次阅读 多人点赞 2014-09-04 11:33:57
    一、 C++ 输入输出的含义以前所用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上。从操作系统(Linux)的角度看,每一个与主机相连的输入输出设备都被看作一个文件。程序的输入...
  • 计算机输入输出系统

    千次阅读 2009-06-23 19:48:00
    计算机输入输出系统摘自《操作系统精髓与设计原理》BY William Stallings刘建文略译(http://blog.csdn.net/keminlau) KEY:功能 逻辑分层 功能分步 系统 INTRO I/O子系统可能是操作系统设计最麻烦的部分了。...
  • 输入输出控制方式

    千次阅读 热门讨论 2015-04-12 11:22:34
    执行输入输出指令以及存储器读写指令来完成的。一般而言, CPU 管理外围设备的输入输出控制方式有 5 种:程序查询方式、中断方式、 DMA 方式(直接内存存取)、通道方式、外围处理机方式,前两种方式由软件实现,...
  • C语言文件的输入输出函数

    千次阅读 2012-10-21 10:34:13
    C语言文件的输入输出函数  C语言提供了两类关于文件的函数。一类称做标准文件函数也称缓冲型文件函数, 这是ANSI标准定义的函数; 另一类叫非标准文件函数, 也称非缓冲型文件函数。这类函数最早公用于UNIX操作系统, ...
  • 对C语言输入输出流和缓冲区的深入理解

    千次阅读 多人点赞 2018-08-28 07:47:00
    对C语言输入输出流和缓冲区的深入理解 2015年10月06日 10:08:17 阅读数:15202更多 个人分类: C语言之路 导读:对C语言输入输出流和缓冲区的深入理解,C语言缓冲区(缓存)详解,缓冲区又称为缓存,这些存储...
  • 项目管理九大知识点输入输出

    千次阅读 2018-06-17 10:13:36
    项目管理九大知识点输入输出一、 项目整体管理1、制订项目章程;2、制订项目范围说明书(初步);3、制订项目管理计划;4、指导和管理项目实施;5、监督和控制项目工作;6整体变更控制;7、项目收尾1、制订项目章程...
  • C++的输入输出流和缓冲区

    千次阅读 2011-11-05 14:49:27
    一、 C++ 输入输出的含义  以前所用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上。从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件。程序的输入指的...
  • linux kernel下输入输出console如何实现

    万次阅读 2014-11-17 17:02:28
    kernel下的console是输入输出设备driver中实现的简单的输出console,只实现write函数,并且是直接输出到设备。 user空间下的console,实际就是tty的一个例子,所有操作函数都继承与tty,全功能,可以打开 读写 关闭...
  • 输入 T&T 输出 1.制定项目章程 1.协议 2.项目工作说明书 3.商业论证 4.事业环境因素 5.组织过程资产 1.专家判断 2.引导技术 1.项目章程 2.制定项目...
  • 文章目录Chapter5:输入输出接口P0~P35.0 概述5.1 PO~P3端口的功能和内部结构5.1.1 P0~P3端口的功能5.1.2 P0~P3端口内部结构5.2 PO~P3端口的编程举例5.3 用并行口设计LED数码显示5.4 用并行口设计键盘电路 ...
  • [STM32]STM32F407系列教程之二,gpio输入输出实验
  • 【51/STM32】详解单片机GPIO口输入输出的各种模式

    千次阅读 多人点赞 2020-05-10 18:54:04
    通用型输入输出端口,简称GPIO口,是单片机与其他外围设备和电路进行信息交换和控制的桥梁。本文从复习模电中所学的场效应管开始,逐步引出开漏输出与推挽输出的概念及阐述其原理,并结合点亮一盏LED灯的实例进一步...
  • 对通用输入输出GPIO的深入理解

    万次阅读 2014-03-21 14:50:50
    http://bbs.21ic.com/blog-804662-97083.html GPIO的各种模式 ... GPIO管脚可以被配置为多种工作模式,其中有3种比较常用:高阻输入、推挽输出、开漏输出  1. 高阻输入(Input)  
  • 熟悉Keil uVision5和Proteus集成开发软件的工作环境和使用方法; 掌握通用I/O口基本工作原理; 掌握通用I/O接口电路设计方法; 熟练运用C语言或汇编语言对I/O端口进行操作; 二、实验任务 1.基本任务 单片机P0...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 163,381
精华内容 65,352
关键字:

判断输入输出软件