精华内容
下载资源
问答
  • 输入输出设备有:1、MPC一般而言,配备了多媒体的硬件系统和相应的软件系统,使其具有综合处理图、文、声、像等信息的功能。这种计算机称为多媒体计算机。多媒体计算机中使用最广泛的是多媒体个人计算机( Multimedia...

    输入输出设备有:

    1、MPC

    一般而言,配备了多媒体的硬件系统和相应的软件系统,使其具有综合处理图、文、声、像等信息的功能。这种计算机称为多媒体计算机。

    多媒体计算机中使用最广泛的是多媒体个人计算机( Multimedia Personal Computer, MPC)MPC同时也是一种工业标准,所以,人们经常所讲的多媒体个人计算机指的是符合MPC标准的、具有多媒体功能的个人计算机,简称MPC.

    2、扫描仪

    扫描仪是一种图像输入设备,利用光电转换原理,通过扫描仪光电的移动或原稿的移动,把黑白或彩色的原稿信息数字化后输入到计算机中。

    3、数码相机

    是一种利用 电子传感器把光学影像转换成电子数据的照相机。主要由镜头,图像传感器,AD转换器,MPU, 存储芯片,LCD组成。镜头:数码相机镜头作用与普通相机镜头作用相同,取景。

    9f1fb6dc6203b926502425b63247a0d7.png

    4、显示器(display)

    通常也被称为监视器,它是一种将一 定的电子文件通过特定的传输设备显示到屏幕上再反射到人眼的显示工具。

    5、投影仪

    是一种可以将图像或视频投射到幕布上的设备,投影机包括核心投影成像部件、光学引擎、电气控制和接口三大主要部分,是一种用来放大显示图像或视频的投影设备号。根据工作方式不同,有CRT, LCD, DLP等不同类型。

    6、麦克风

    麦克风(Microphone) ,学名为传声器,微音器。 麦克风是将音频信号转换为电信号的能量转换器件。基本原理是将空气中的变动压力波转化成变动电信号。

    7、音箱

    音箱 (Speaker)是将音频信号还原成声音的一种设备。通俗的讲就是指放置扬声器(俗称喇叭)的箱体。

    展开全文
  • 多媒体技术第2章任务3了解输入输出设备的功能.pptx
  • 本系列介绍ffmpeg命令行中有关-devices输入输出设备的支持和使用。 输入设备(input devices)用于采集/抓取来自连接到系统的多媒体设备的数据,比如采集麦克风/话筒的音频采样数据,桌面屏幕图像数据,摄像头/相机...

    ffmpeg命令系列:

    FFmpeg命令行使用手册-protocols协议汇总篇
    FFmpeg命令行使用手册-devices输入输出设备汇总篇

    一、前言

    本系列介绍ffmpeg命令行中有关-devices输入输出设备的支持和使用。

    输入设备(input devices)用于采集/抓取来自连接到系统的多媒体设备的数据,比如采集麦克风/话筒的音频采样数据,桌面屏幕图像数据,摄像头/相机图像数据等。

    输出设备(output devices)用于将多媒体数据写出到系统的输出设备中,比如音频播放设备,窗口,图形渲染设备(openGL上下文、SDL)等。

    二、参考资料

    本文参考自ffmpeg官方文档:https://ffmpeg.org/ffmpeg-devices.html

    三、如何下载和安装ffmpeg

    windows平台下载:https://download.csdn.net/download/eguid_1/12567936
    mac平台下载:https://download.csdn.net/download/eguid_1/12607297
    linux平台下载:linux发行版较多,有些发行版支持ffmpeg,不一一提供,提供ffmpeg官方提供的两个下载链接
    http://ffmpeg.org/download.html

    https://johnvansickle.com/ffmpeg/

    四、如何查看ffmpeg支持的所有输入输出设备

    使用ffmpeg命令列出所有ffmpeg支持的设备

    ffmpeg.exe -devices

    注意:ffmpeg支持的设备列表与每台机器的系统环境和设备环境有关,每台机器可能都不同。

    五、ffmpeg支持的devices设备列表

    输入设备(input devices)

    1. alsa

    ALSA(高级Linux声音体系结构)输入设备。
    要在配置期间启用此输入设备,您需要在系统上安装libasound。
    该设备允许从ALSA设备进行捕获。要捕获的设备的名称必须是ALSA卡标识符。

    alsa详细信息:https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html

    1.1 ffmpeg命令

    ffmpeg -f alsa -i hw:0 alsaout.wav

    1.2 参数说明

    hw:CARD[,DEV[,SUBDEV]]

    三个参数顺序为:CARD,DEV,SUBDEV
    CARD:指定卡号或标识符
    DEV:设备号
    SUBDEV:子设备号(-1表示任意)

    2. android_camera

    Android相机输入设备。
    基于Android Camera2 NDK API,该API在API级别为24+的设备上可用。在配置过程中会自动检测到android_camera的可用性。
    该设备允许从集成在Camera2 NDK API中的Android设备上的所有相机捕获。可用的摄像机在内部进行枚举,可以使用camera_index参数进行选择。输入文件字符串将被丢弃。
    通常,背面摄像头的索引为0,而正面摄像头的索引为1。

    3. avfoundation

    AVFoundation是Apple(苹果公司)当前推荐的多媒体框架,可用于在OSX> = 10.7和iOS上进行流式抓取图像和音频。
    可以通过ffmpeg -f avfoundation -list_devices true -i ""列出当前macOS或iOS上支持的抓取设备名称和对应设备的索引号

    3.1 ffmpeg命令

    ffmpeg -f avfoundation -i “0:0” out.avi

    将索引号为0的视频设备和索引号0的音频设备录制成out.avi视频文件

    3.2 参数说明

    -i “[[VIDEO]:[AUDIO]]”

    video:视频设备索引号
    audio:音频设备索引号
    索引号通过ffmpeg -f avfoundation -list_devices true -i ""命令查看。

    4. bktr

    BSD视频输入设备。

    5. decklink

    decklink输入设备为Blackmagic DeckLink设备提供捕获功能。

    6.dshow

    Windows DirectShow输入设备,用于采集windows下的视频和音频设备。
    通过命令 ffmpeg -list_devices true -f dshow -i dummy 查看支持的设备列表,包含设备名称,设备类型等信息。

    6.1 ffmpeg命令

    ffmpeg -f dshow -i video=“Camera”:audio=“Microphone”

    打开摄像头和麦克风

    6.2 参数说明

    TYPE=NAME[:TYPE=NAME]

    TYPE:设备类型,video或者audio
    NAME:设备名称(对应命令 ffmpeg -list_devices true -f dshow -i dummy 中输出的设备名称)

    7. fbdev

    Linux帧缓冲输入设备。
    Linux帧缓冲区是独立于图形硬件的图形抽象层,用于在计算机监视器(通常在控制台)上显示图形。通过文件设备节点(通常是/ dev / fb0)访问它。
    详情信息:http://linux-fbdev.sourceforge.net/

    8.gdigrab

    基于Win32 GDI的屏幕捕获设备。可以捕获Windows桌面屏幕显示区域的画面图像,包含windows窗口显示画面。

    8.1 ffmpeg命令

    捕获桌面屏幕指定区域的画面图像(不加-offset_x 和 -offset_y就是捕获全屏)

    ffmpeg -f gdigrab -framerate 6 -offset_x 10 -offset_y 20 -video_size vga -i desktop out.mpg

    捕获计算器窗口画面图像

    ffmpeg -f gdigrab -framerate 6 -i title=Calculator out.mpg

    8.2 参数说明

    framerate:帧率
    desktop:desktop是指输入设备是桌面屏幕
    title=window_title :window_title是windows窗口的标题,注意不是进程名称
    draw_mouse:是否绘制鼠标,0:不绘制鼠标,1:绘制鼠标(如果为空默认为1)
    -offset_x:捕获的区域X坐标,屏幕左上角为起始坐标(0,0),右下角为(screenSize,screenSize)
    -offset_y:捕获的区域Y坐标

    9. iec61883

    使用libiec61883的FireWire DV / HDV输入设备。

    10. jack

    JACK输入设备

    11. kmsgrab

    KMS视频输入设备。
    将与指定的CRTC或平面关联的KMS扫描输出帧缓冲区捕获为DRM对象,并将其传递给其他硬件功能。
    需要DRM主服务器或CAP_SYS_ADMIN才能运行。

    12. lavfi

    Libavfilter输入虚拟设备。
    该输入设备从libavfilter过滤器图的打开的输出垫读取数据。
    对于每个filtergraph打开的输出,输入设备将创建一个对应的流,该流映射到生成的输出。当前仅支持视频数据。过滤器图是通过选项图指定的。

    13. libcdio

    基于libcdio的音频CD输入设备。
    要在配置期间启用此输入设备,您需要在系统上安装libcdio。它需要配置选项–enable-libcdio。
    此设备允许从音频CD播放和抓取。

    14. libdc1394

    IIDC1394输入设备,基于libdc1394和libraw1394。

    15. openal

    OpenAL输入设备通过有效的OpenAL 1.1实施在所有系统上提供音频捕获。OpenAL标头和库应作为OpenAL实施的一部分提供,或作为其他下载(SDK)提供。

    16. oss

    打开声音系统输入设备。
    提供给输入设备的文件名是代表OSS输入设备的设备节点,通常设置为/ dev / dsp。

    17. pulse

    pulseAudio输入设备。
    提供给输入设备的文件名是源设备或字符串“ default”。

    18. sndio

    sndio输入设备。
    提供给输入设备的文件名是代表sndio输入设备的设备节点,通常设置为/ dev/audio0。

    19. video4linux2, v4l2

    Video4Linux2输入视频设备。“ v4l2”可以用作“ video4linux2”的别名。
    如果FFmpeg是使用v4l-utils支持构建的(通过使用–enable-libv4l2配置选项),则可以将其与-use_libv4l2输入设备选项一起使用。
    要抓取的设备的名称是文件设备节点,通常,Linux系统会在将设备(例如USB网络摄像头)插入系统时自动创建此类节点,并且名称为/ dev / videoN,其中N是与设备关联的数字。
    Video4Linux2设备通常支持一组有限的widthxheight大小和帧速率。您可以使用-list_formats all查看Video4Linux2设备支持的功能。某些设备(例如电视卡)支持一种或多种标准。可以使用-list_standards all列出所有受支持的标准。
    时间戳记的时基为1微秒。根据内核版本和配置的不同,时间戳可能来自实时时钟(Unix纪元起源)或单调时钟(通常在引导时起源,不受NTP或手动更改时钟的影响)。 -timestamps abs或-ts abs选项可用于强制转换为实时时钟。

    20. vfwcap

    VfW(Windows视频)捕获输入设备。作为输入传递的文件名是捕获驱动程序号,范围从0到9,一般用于捕获摄像头图像。
    可以使用“ list”作为文件名来查看支持的设备列表。其他任何文件名将被解释为设备号0。

    20.1 ffmpeg命令

    查看本机支持的设备列表

    ffmpeg -y -f vfwcap -i list

    捕获摄像头图像并保存成mp4文件

    ffmpeg -y -f vfwcap -i 0 out.mp4

    20.2 参数说明

    video_size:设置抓取的图像大小(例如:800x600)
    framerate:帧率,默认30帧

    21. x11grab

    X11视频输入设备。可以捕获X11显示器的区域。

    输出设备

    1. alsa

    ALSA(高级Linux声音体系结构)输出设备。

    2. AudioToolbox

    AudioToolbox输出设备。
    允许本机输出到OSX上的CoreAudio设备。

    3. caca

    CACA输出设备。
    此输出设备允许在CACA窗口中显示视频流。每个应用程序只允许一个CACA窗口,因此在一个应用程序中只能有一个此输出设备的实例。

    4. decklink

    decklink输出设备为Blackmagic DeckLink设备提供播放功能。

    5. fbdev

    Linux帧缓冲输出设备。
    Linux帧缓冲区是独立于图形硬件的图形抽象层,用于在计算机监视器(通常在控制台)上显示图形。通过文件设备节点(通常是/ dev / fb0)访问它。
    更多详细信息请查看:http://linux-fbdev.sourceforge.net/

    6. opengl

    OpenGL输出设备。
    此输出设备允许渲染到OpenGL上下文。上下文可以由应用程序提供,也可以创建默认的SDL窗口。

    7. oss

    OSS(开放声音系统)输出设备。

    8. pulse

    PulseAudio输出设备。
    更多信息请查看:http://www.pulseaudio.org

    9. sdl

    SDL(简单DirectMedia层)输出设备。“ sdl2”可以用作“ sdl”的别名。
    此输出设备允许在SDL窗口中显示视频流。每个应用程序只允许一个SDL窗口,因此在一个应用程序中只能有此输出设备的一个实例。
    更多sdl信息请查看:http://www.libsdl.org/

    10. sndio

    sndio音频输出设备。

    11. v4l2

    Video4Linux2输出设备。

    12. xv

    XV(XVideo)输出设备。可以在X Window System窗口中显示视频流。

    展开全文
  • 除了CPU和存储器外,输入输出模块也是计算机的关键部分。 I/O设备与主机交换信息的三种方式为程序查询、中断和DMA。 1、早期阶段 I/O设备与主存交换信息都必须经过CPU。 2、接口模块和DMA阶段 接口中设有...

    除了CPU和存储器外,输入输出模块也是计算机的关键部分。

     

    I/O设备与主机交换信息的三种方式为程序查询、中断和DMA。

     

    1、早期阶段

    I/O设备与主存交换信息都必须经过CPU。

     

    2、接口模块和DMA阶段

    接口中设有数据通路和控制通路,数据经过接口既起到缓冲作用,又可完成串-并转换。

    控制通路用以传送CPU向I/O设备发出的各种控制命令,或使CPU接收来自I/O设备的反馈信号。

     

    接口模块实现了CPU和I/O设备并行工作,主机与I/O设备交换信息时,CPU要中断现行程序,即CPU和I/O设备还不能做到绝对的并行工作。

     

    DMA技术

    I/O设备和主存之间有一条数据通路,I/O设备可以与主存直接交换信息,使CPU在I/O设备与主存交换信息时能继续完成自身的工作。

     

    3、具有通道结构的阶段

    通道是用来负责管理I/O设备以及实现主存与I/O设备之间交换信息的部件,可以视为一种具有特殊功能的处理器。

    通道有专用的通道指令。

     

    4、具有I/O处理机阶段

    独立于主机工作,即可完成I/O通道要完成的I/O控制,又可完成码制交换、格式梳理、数据块检错、纠错等操作。

     

     

     

    输入输出系统由I/O软件和I/O硬件组成

    I/O软件

    1、将用户编制的程序输入主机内

    2、将运算结果输出给用户

    3、实现输入输出系统与主机工作的协调等

     

    I/O指令

    I/O指令是机器指令的一种。

    操作码 命令码 设备码

    操作码字段可作为I/O指令与其他指令(如访存指令、算逻指令、控制指令等)的判别代码;命令码体现I/O设备的具体操作;设备码是多台I/O设备的选择码。

     

    通道指令

    通道指令是对具有通道的I/O系统专门设置的指令。

    通道指令又称为通道控制字,它是通道用于执行I/O操作的指令,可以由管理程序存放在主存的任何地方,由通道从主存中取出并执行。

    通道程序即由通道指令组成,它完成某种外围设备与主存之间传送信息的操作。

     

     

     

    I/O硬件

    输入输出系统的硬件组成一般包括接口模块和I/O设备两大部分。

    一个通道可以和一个以上的设备控制器相连,一个设备控制器又可控制若干台同一类型的设备。

     

     

     

     

    I/O设备与主机的联系方式

    1、I/O设备编址方式

    分为统一编址和不统一编址。

    统一编址就是将I/O地址看作是存储器地址的一部分。

    不统一编址就是指I/O地址和存储器地址是分开的。

     

    2、设备寻址

    每台设备都赋予一个设备号,可由I/O指令的设备码字段直接指出该设备的设备号

     

    3、传送方式

    分为并行传送和串行传送。

    不同的传送方式需配置不同的接口电路。

     

    4、联络方式

    分为三种方式:

    1、立即响应方式

    2、异步工作采用应答信号联络

    3、同步工作采用同步时标联络

     

    5、I/O设备与主机的连接方式

    采用辐射式和总线式连接方式。

     

     

     

    I/O设备与主机信息传送的控制方式

    1、程序查询方式

    2、程序中断方式

    3、直接存储器存取方式DMA

    4、I/O通道方式

    5、I/O处理机方式

     

     

     

    I/O设备

    简称外设。

    I/O设备通常结构为:设备控制器和机、电、磁、光部件。

    I/O设备大致分为三类:

    1、人机交互设备

    2、计算机信息的存储设备

    3、机-机通信设备

     

    输入设备:键盘、鼠标、触摸屏、其他输入设备。

    触摸屏:电阻式、电容式、表面超声波式、扫描红外线式和压感式。

    其他输入设备:光笔、画笔与图形版、图像输入设备。

     

    输出设备

    显示设备

    按显示器划分:阴极射线管显示器、液晶显示器、等离子显示器

    按显示内容划分:字符显示器、图形显示器、图像显示器

    按显示功能划分:普通显示器、显示终端

     

    CRT重要技术指标:分辨率和灰度等级

    刷新频率大于30次/秒,人眼不会闪烁

    不断的刷新,瞬时图片保存在存储器中,称为刷新存储器

     

     

    打印设备

    打印设备分为打击式和非打击式

    点阵针式打印机

    激光打印机

    喷墨打印机

     

    比较:

    点阵针式打印机的字符点阵用于控制打印针的驱动电路;

    激光打印机的字符点阵脉冲信号用于控制激光束;

    喷墨打印机的字符点阵信息控制墨滴的运动轨迹;

     

     

     

    其他I/O设备

    1、终端设备:显示器和键盘组成

    2、A/D与D/A转换器

    3、汉子处理设备

     

     

     

    多媒体技术

    多媒体的核心词是媒体,音乐、语言、图片、文件、书籍等

     

    多媒体计算机关键技术

    1、视频和音频数据的压缩与解压缩技术

    2、多媒体专用芯片

    3、大容量存储器

    4、适用于多媒体技术的软件

     

     

     

    I/O接口

    接口可以看做是两个系统或两个部件之间的交接部分。

    不同的I/O设备都有其相应的设备控制器

     

    I/O接口可以做设备选择、数据缓冲、串-并格式转换、电平转换、传送控制命令、保存状态信息。

     

    接口和端口不同,端口指接口电路中的一些寄存器:数据端口、控制端口、状态端口。

     

     

    接口的功能和组成

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

    包括数据线、设备选择线、命令线和状态线

     

    2、接口的功能和组成

    选址功能、传送命令的功能、传送数据的功能、反应I/O设备工作状态的功能

     

     

     

    接口类型

    1、按数据传送方式分为并行接口和串行接口

    2、按功能选择的灵活性分类分为可编程接口和不可编程接口

    3、按通用性分类分为通用接口和专用接口

    4、按数据传送的控制方式分为程序型接口和DMA型接口

     

     

     

     

    程序查询方式

    测试指令、传送指令、转移指令

     

    程序中断方式

    当出现异常情况或者特殊请求时,计算机停止现行的程序运行,转向对这些异常情况和特殊情求的处理,处理后再返回到现行程序的间断处,继续执行原程序,这就是中断。

    保护现场、中断服务(设备服务)、恢复现场、中断返回

     

    DMA方式

    停止CPU访问主存、周期挪用(周期窃取)、DMA与CPU交替访问

    预处理、数据传送、后处理

    选择型DMA接口、多路型DMA接口

     

     

    展开全文
  • 本书系统地介绍了多媒体计算机常用的外部设备。包括输入设备、输出设备、外存储设备、网络设备、多媒体硬件设备,重点介绍了常用外部设备产品的性能、结构及其工作原理。 周怡聪主编 北方交通大学出版社
  • java之九 基本输入输出

    千次阅读 2016-05-23 18:48:10
    流的概念 ...这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文

     

    流的概念

     

    视频课堂:https://edu.csdn.net/course/play/8222

    Java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。 Java中流的实现是在java.io包定义的类层次结构内部的。

    注意:如果你熟悉C/C++,你已经对流的概念很熟悉了。JAVA中流的实现跟C/C++中有些相似。

    字节流和字符流

     

    Java 2 定义了两种类型的流:字节类和字符类。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流读取或书写二进制数据。字符流(character stream)为字符的输入和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。

    Java的原始版本(Java 1.0)不包括字符流,因此所有的输入和输出都是以字节为单位的。Java 1.1中加入了字符流,某些字节形式的类和方法不受欢迎。这也是为什么没用字符流的老代码在适当的地方需要更新的原因。

    需要声明:在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。下面是对字节流和字符流的概述。

    字节流类

    字节流由两个类层次结构定义。在顶层有两个抽象类:InputStream 和 OutputStream。

    每个抽象类都有多个具体的子类,这些子类对不同的外设进行处理,例如磁盘文件,网络连接,甚至是内存缓冲区。字节流类显示于表9-1中。本章的后面将讨论一些这样的类。其他的类的描述在第2部分。记住,要使用流类,必须导入Java.io包。

    表 9-1  字节流类

     

    抽象类InputStream和 OutputStream定义了实现其他流类的关键方法。 最重要的两种方法是read()和write(),它们分别对数据的字节进行读写。两种方法都在InputStream  和OutputStream中被定义为抽象方法。它们被派生的流类重载。

    字符流类

    字符流类由两个类层次结构定义。顶层有两个抽象类:Reader和Writer。这些抽象类处理统一编码的字符流。Java中这些类含有多个具体的子类。字符流类如表9-2所示。

    表 9-2  字符流的输入/输出类

     

    抽象类Reader和Writer定义了几个实现其他流类的关键方法。 其中两个最重要的是read()和write(),它们分别进行字符数据的读和写。这些方法被派生流类重载。

    预定义流

     

    所有的Java程序自动导入java.lang包。该包定义了一个名为System的类,该类封装了运行时环境的多个方面。例如,使用它的某些方法,你能获得当前时间和与系统有关的不同属性。System 同时包含三个预定义的流变量,in,out和err。这些成员在System中是被定义成public 和static型的,这意味着它们可以不引用特定的System对象而被用于程序的其他部分。

    System.out是标准的输出流。默认情况下,它是一个控制台。System.in是标准输入,默认情况下,它指的是键盘。System.err指的是标准错误流,它默认是控制台。然而,这些流可以重定向到任何兼容的输入/输出设备。

    System.in 是inputStream的对象;System.out和System.err是PrintStream的对象。它们都是字节流,尽管它们用来读写外设的字符。如果愿意,你可以用基于字符的流来包装它们。 

    前面的章节在例题中已经用到过System.out。你可以以同样的方式使用System.err。下面对此进行解释,你会看到使用System.in有一点复杂。

    读取控制台输入

     

    在Java 1.0中,完成控制台输入的惟一途径是字节流,使用该方法的老代码依然存在。今天,运用字节流读取控制台输入在技术上仍是可行的,但这样做需要用到不被赞成的方法,这种做法不值得推荐。Java 2中读取控制台输入的首选方法是字符流,它使程序容易符合国际标准并且易于维护。

    注意: Java没有像标准C的函数scanf()或C++输入操作符那样的统一的控制台输入方法。

    Java中,控制台输入由从System.in读取数据来完成。为获得属于控制台的字符流,在BufferedReader对象中包装System.in。BufferedReader 支持缓冲输入流。它最常见的构造函数如下:

    BufferedReader(Reader inputReader)

    这里,inputReader是链接被创建的BufferedReader实例的流。Reader是一个抽象类。它的一个具体的子类是InputStreamReader,该子类把字节转换成字符。为获得链接System.in的一个InputStreamReader的对象,用下面的构造函数:

    InputStreamReader(InputStreaminputStream) 因为System .in引用了InputStream 类型的对象,它可以用于inputStream。综上所述,下面的一行代码创建了与键盘相连的BufferedReader对象。

    BufferedReader br = newBufferedReader(new

                                             InputStreamReader(System.in));

    当该语句执行后,br是通过System.in生成的链接控制台的字符流。

    读取字符

     

    从BufferedReader读取字符,用read()。我们所用的read()版本如下:

    int read( ) throws IOException

    该方法每次执行都从输入流读取一个字符然后以整型返回。当遇到流的末尾时它返回-1。你可以看到,它要引发一个IOException异常。

    下面的例子程序演示了read()方法,从控制台读取字符直到用户键入“q”:

    // Use a BufferedReader to readcharacters from the console.

    import java.io.*;

     

    class BRRead {

     public static void main(String args[]) 

        throws IOException

     {

        char c;

        BufferedReader br = new

                BufferedReader(newInputStreamReader(System.in));

        System.out.println("Enter characters,'q' to quit.");

     

     

        // read characters

        do {

          c = (char) br.read();

          System.out.println(c);

        } while(c != 'q');

     }

    }

    下面是程序运行:

    Enter characters, 'q' to quit.

    123abcq

    1

    2

    3

    a

    b

    c

    q

    程序的输出看起来与预想的略有不同,因为System.in在默认情况下是以行来缓冲的。

    这意味着在你键入ENTER以前实际上是没有输入的。你能猜想,这不能充分体现交互式控制台输入条件下read()的独特价值。

    读取字符串

     

    从键盘读取字符串,使用readLine()。它是BufferedReader  类的成员。它的通常形式如下:

    String readLine( ) throwsIOException

    它返回一个String对象。

    下面的例子阐述了BufferedReader类和readLine()方法; 程序读取和显示文本的行直到键入“stop”:

    // Read a string from consoleusing a BufferedReader.

    import java.io.*;

     

    class BRReadLines {

     public static void main(String args[])

    throwsIOException

    {

        // create a BufferedReader using System.in

        BufferedReader br = new BufferedReader(new

                               InputStreamReader(System.in));

        String str;

     

        System.out.println("Enter lines oftext.");

        System.out.println("Enter 'stop' toquit.");

        do {

          str = br.readLine();

          System.out.println(str);

        } while(!str.equals("stop"));

      }

    }

    下面的例题生成了一个小文本编辑器。它创建了一个String对象的数组,然后依行读取文本,把文本每一行存入数组。它将读取到100行或直到你按“stop”才停止。该例运用一个BufferedReader类来从控制台读取数据。

    // Atiny editor.

    importjava.io.*;

     

    classTinyEdit {

      public static void main(String args[]) 

        throws IOException

      {

        // create a BufferedReader using System.in

        BufferedReader br = new BufferedReader(new

                               InputStreamReader(System.in));

        String str[] = new String[100];

     

        System.out.println("Enter lines oftext.");

        System.out.println("Enter 'stop' toquit.");

        for(int i=0; i<100; i++) {

          str[i] = br.readLine();

          if(str[i].equals("stop"))

    break;

        }

     

        System.out.println("\nHere is yourfile:");

     

        // display the lines 

        for(int i=0; i<100; i++) {

          if(str[i].equals("stop"))break;

          System.out.println(str[i]);

        }

      }

    }

    下面是输出部分:

    Enterlines of text.

    Enter‘stop’ to quit.

    This isline one.

    This isline two.

    Javamakes working with strings easy.

    Justcreate String objects.

    stop

    Here isyour file:

    This isline one.

    This isline two.

    Javamakes working with strings easy.

    Justcreate String objects.

     

    向控制台写输出

     

     

    控制台输出由前面描述过的print() 和 println( )来完成最为简单, 它们被用在本书的大多数例题中。这两种方法由PrintStream(System.out引用的对象类型)定义。尽管System.out是一个字节流,用它作为简单程序的输出是可行的。字符流输出在下节介绍。 因为PrintStream是从OutputStream派生的输出流,它同样实现低级方法write( ),write( )可用来向控制台写数据。PrintStream  定义的write( )的最简单的形式如下:

    void write(int byteval)

    该方法按照byteval指定的数向文件写字节。尽管byteval  定义成整数,但只有低位的8个字节被写入。下面的短例用write( )向屏幕输出字符“A”,然后是新的行。

    // Demonstrate System.out.write().

    class WriteDemo {

     public static void main(String args[]) {

        int b;

     

        b = 'A';

        System.out.write(b);

        System.out.write('\n');

     }

    }

    一般不常用write( )来完成向控制台的输出(尽管这样做在某些场合非常有用),因为 print()和println( ) 更容易用。

    PrintWriter类

     

     

    尽管Java允许用System.out向控制台写数据,但建议仅用在调试程序时或在例题中,这在本书中得到充分体现。对于实际的程序,Java推荐的向控制台写数据的方法是用PrintWriter流。PrintWriter是基于字符的类。用基于字符类向控制台写数据使程序更为国际化。

    PrintWriter定义了多个构造函数,我们所用到的一个如下:

    PrintWriter(OutputStreamoutputStream, boolean flushOnNewline)

    这里,outputStream是OutputStream类的对象,flushOnNewline控制Java是否在println( ) 方法被调用时刷新输出流。如果flushOnNewline为true,刷新自动发生,若为false,则不发生。

    PrintWriter支持所有类型(包括Object)的print( )和println( )方法,这样,你就可以像用System.out那样用这些方法。 如果遇到不同类型的情况, PrintWriter方法调用对象的toString( )方法并打印结果。

    用PrintWriter向外设写数据,指定输出流为System.out并在每一新行后刷新流。例如这行代码创建了与控制台输出相连的PrintWriter类。

    PrintWriter pw = newPrintWriter(System.out, true);

    下面的应用程序说明了用PrintWriter处理控制台输出的方法:

    // Demonstrate PrintWriter

    import java.io.*;

     

    public class PrintWriterDemo {

     public static void main(String args[]) {

        PrintWriter pw = newPrintWriter(System.out, true);

        pw.println("This is a string");

        int i = -7;

        pw.println(i);

        double d = 4.5e-7;

        pw.println(d);

      }

    }

    该程序的输出如下:

    This is astring

    -7

    4.5E-7

    记住,在你学习Java或调试程序时用System.out向控制台写简单文本输出是没有错的。但是使用PrintWriter使实际的应用程序更容易国际化。因为在本书所示的例题程序中用PrintWriter并没有多大的优势,所以我们继续用System.out来向控制台输出。

    文件的读写

     

     

    Java为你提供了一系列的读写文件的类和方法。在Java中,所有的文件都是字节形式的。

    Java提供从文件读写字节的方法。而且,Java允许在字符形式的对象中使用字节文件流。这项技术在第2部分描述。本章说明基本的文件输入/输出。

    两个最常用的流类是FileInputStream和FileOutputStream,它们生成与文件链接的字节流。为打开文件,你只需创建这些类中某一个类的一个对象,在构造函数中以参数形式指定文件的名称。这两个类都支持其他形式的重载构造函数。下面是我们将要用到的形式:

    FileInputStream(String fileName)throws FileNotFoundException

    FileOutputStream(String fileName)throws FileNotFoundException

    这里,fileName指定需要打开的文件名。当你创建了一个输入流而文件不存在时,引发FileNotFoundException异常。对于输出流,如果文件不能生成,则引发FileNotFoundException异常。如果一个输出文件被打开,所有原先存在的同名的文件被破坏。

    注意:在早期的Java版本中,当输出文件不能创建时FileOutputStream()引发一

    void close( ) throws IOException

    为读文件,可以使用在FileInputStream中定义的read( )方法。我们用到的如下:

    int read( ) throws IOException 该方法每次被调用,它仅从文件中读取一个字节并将该字节以整数形式返回。当读到文件尾时,read( )返回-1。该方法可以引发IOException异常。

    下面的程序用read()来输入和显示文本文件的内容,该文件名以命令行形式指定。注意try/catch块处理程序运行时可能发生的两个错误——未找到指定的文件或用户忘记包括文件名了。当你用命令行时也可以用这样的方法。

    /* Display a text file.

     

      To use this program, specify the name 

      of the file that you want to see.

      For example, to see a file called TEST.TXT,

      use the following command line.

     

      Java ShowFile TEST.TXT

     

    */

     

    import java.io.*;

     

    class ShowFile {

     public static void main(String args[]) 

        throws IOException

     {

        int i;

        FileInputStream fin;

     

        try {

          fin = new FileInputStream(args[0]);

        } catch(FileNotFoundException e) {

          System.out.println("File NotFound");

          return;

        } catch(ArrayIndexOutOfBoundsException e) {

          System.out.println("Usage: ShowFileFile");

          return;

        }

    // read characters until EOF isencountered

        do {

          i = fin.read();

          if(i != -1)

    System.out.print((char)i);

        } while(i != -1);

     

        fin.close();

     }

    }

    向文件中写数据,需用FileOutputStream定义的write()方法。它的最简单形式如下:

    void write(int byteval) throwsIOException

    该方法按照byteval指定的数向文件写入字节。尽管byteval作为整数声明,但仅低8位字节可以写入文件。 如果在写的过程中出现问题,一个IOException被引发。 下面的例子用write()拷贝一个文本文件:

    /* Copy a text file.

     

      To use this program, specify the name 

      of the source file and the destination file.

      For example, to copy a file called FIRST.TXT

      to a file called SECOND.TXT, use the following

      command line.

     

      Java CopyFile FIRST.TXT SECOND.TXT

    */

     

    import java.io.*;

     

    class CopyFile {

     public static void main(String args[]) 

        throws IOException

     {

        int i;

        FileInputStream fin;

        FileOutputStream fout;

     

        try {

          // open input file

          try {

            fin = new FileInputStream(args[0]);

          } catch(FileNotFoundException e) {

            System.out.println("Input File NotFound");

            return;

          }

     

          // open output file

          try {

            fout = new FileOutputStream(args[1]);

          } catch(FileNotFoundException e) {

            System.out.println("Error OpeningOutput File");

            return;

    }

        } catch(ArrayIndexOutOfBoundsException e) {

          System.out.println("Usage: CopyFileFrom To");

          return;

        }

     

        // Copy File

        try {

          do {

            i = fin.read();

            if(i != -1) fout.write(i);

          } while(i != -1);

        } catch(IOException e) {

          System.out.println("FileError");

        }

     

        fin.close();

        fout.close();

     }

    }

    注意本程序中和前面ShowFile程序中处理潜在输入/输出错误的方法。不像其他的计算机语言,包括C和C++,这些语言用错误代码报告文件错误,而Java用异常处理机制。这样不仅是文件处理更为简洁,而且使Java正在执行输入时容易区分是文件出错还是EOF条件问题。在C/C++中,很多输入函数在出错时和到达文件结尾时返回相同的值(也就是说,在C/C++中,EOF情况与输入错误情况映射相同)。这通常意味着程序员必须还要编写特殊程序语句来判定究竟是哪种事件发生。Java中,错误通过异常引发,而不是通过read( )的返回值。这样,当read( )返回-1时,它仅表示一点:遇到了文件的结尾。

    小应用程序基础

     

     

    本书中前面所有的例子都是Java应用程序。然而,应用程序只是Java程序的一种。另一种类型的程序是applet(小应用程序)。如第1章提到的,小应用程序(applet)是访问internet服务器,在internet上传播的,自动安装的,作为部分Web文档运行的小应用程序。当小应用程序到达客户端,它被限制访问资源,以使它能够在不受病毒威胁和破坏数据完整性的情况下生成一个二进制的多媒体用户界面以及完成复杂的计算。

    用到applet包时,很多关于创建和使用小应用程序的问题会在第2部分见到。然而,有关创建小应用程序的基础问题在这里描述,因为小应用程序与以前所用的程序具有不同的结构。你将看到,小应用程序在几处关键地方与应用程序不同。

    让我们从下面的简单小应用程序开始:

    importjava.awt.*;

    importjava.applet.*;

     

    public class SimpleApplet extendsApplet {

     public void paint(Graphics g) {

    g.drawString("ASimple Applet", 20, 20);

    }

    }

    这个小应用程序以两个import语句开始。第一个导入抽象窗口工具集(AWT)类。小应用程序是通过AWT与用户交流的,而不是通过基于控制台的输入/输出类。AWT包含了对基于视窗的图形界面的支持。你能猜想,AWT是非常庞大和复杂的,关于它的详尽的讨论在本书的第2部分花了好几章。幸运的是,这个简单的小应用程序仅用到了AWT的一点点内容。第二个import语句导入了applet包,该包包含Applet类。每一个小应用程序都必须是Applet的子类。

    程序的下面一行声明了SimpleApplet类。该类必须为public型,因为它的代码会在程序外面被引用。 在SimpleApplet内部声明了paint()。该方法由AWT定义且必须被小应用程序重载。小应用程序每次重新显示输出时都要调用paint()。发生这种情况有多种原因。例如,小应用程序运行的窗口可以被另一窗口重写然后覆盖。或者,小应用程序窗口可以最小化然后恢复。paint()方法在小应用程序启动时也被调用。无论什么原因,当小应用程序需要重画输出时,paint()总被调用。paint()方法有一个Graphics类型的参数,该参数包含描绘小应用程序运行的图形环境的内容。一旦小应用程序需要输出,该内容被用到。在paint( )内调用Graphics类成员drawString(),该方法从指定的X,Y坐标处输出一个字符串。它有下面的常用形式:

    void drawString(String message, int x, inty)

    这里message是以x,y为输出起点的字符串。在Java窗口中,左上角的位置为0,0。在小应用程序中DrawString()的调用使得在坐标20,20处开始显示消息“A Simple Applet”。 

    注意小应用程序没有main()方法,不像Java应用程序,小应用程序不以main()为程序起始。实际上,大多数小应用程序甚至不含main()方法。相反,当小应用程序类名被传输到小应用程序阅读器(appletview)或网络浏览器时它开始执行。在你键入SimpleApplet的源代码后,用你以前编译程序的方法编译该程序。但是,运行SimpleApplet包含一个完全不同的过程。实际上,有两种方法可以运行小应用程序。

    · 在一个兼容Java的网络浏览器,例如Netscape Navigator中执行小应用程序

    ·  使用小应用程序阅读器,例如标准JDK工具,小应用程序阅览器(appletviewer)。

    一个小应用程序阅读器在窗口中执行小应用程序。 这是检测小应用程序最快和最简单的方法。

    上述方法在下面都有阐述。

    为在一个网络浏览器中执行小应用程序,需要编写包含适当APPLET标记的简短的HTML文档。下面是执行SimpleApplet的HTML文件:

    <appletcode="SimpleApplet" width=200 height=60>

    </applet>

    width 和height语句指定了小应用程序用到的显示区域的尺寸(APPLET标记包括几个其他的选项,这在第2部分有详细的描述)。创建文件后,你可以启动浏览器并加载可以执行SimpleApplet的文件。 为使用小应用程序阅读器执行SimpleApplet,你也需执行前面的HTML文件。例如前面所述的HTML文档叫做RunApp.html,则下面的命令行将运行SimpleApplet:

    C:\>appletviewer RunApp.html

    然而,存在一个更方便的方法使测试更快的完成。仅仅在你包含APPLET标记的Java源代码的开头加入一个命令。这样做,你的代码就被一个必要的HTML语句原型证明,你只需启动含有JAVA源码文件的小应用程序阅读器就可以测试你编译过的小应用程序。 如果你使用该方法,SimpleApplet源文件如下:

    importjava.awt.*;

    importjava.applet.*;

    /*

    <appletcode="SimpleApplet" width=200 height=60>

    </applet>

    */

     

    publicclass SimpleApplet extends Applet {

      public void paint(Graphics g) {

        g.drawString("A Simple Applet",20, 20);

      }

    }

    总的来说,你可以使用下面三步来应用小应用程序:

    1.  编写Java源程序。

    2. 编译程序。

    3. 执行小应用程序阅览器,指定小应用程序源文件名称。小应用程序阅览器将在注释中遇到APPLET标记并执行小应用程序。

    SimpleApplet生成的窗口,在小应用程序阅览器中显示。该窗口如下面插图:

     关于小应用程序的专题在本书后面有更详尽的讨论,下面是需要记住的关键点:

    · 小应用程序不一定包含 main( )  方法。

    · 小应用程序必须在小应用程序阅读器或兼容JAVA的浏览器中运行。

    · 用户输入/输出不是由Java的输入/输出流类来完成的。相反,小应用程序运用 AWT提供的界面。

    Transient和volatile修饰符

     

     

    Java定义了两类有趣的修饰符:transient和volatile,这些修饰符用来处理特殊的情况。

    如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。例如:

    class T {

     transient int a; // will not persist

     int b; // will persist

    }

    这里,如果T类的一个对象被写入一个持久的存储区域,a的内容不被保存,但b将被保存。Volatile修饰符告诉编译器被volatile修饰的变量可以被程序的其他部分改变。一种这样的情形是多线程程序(参看第11章的例子)。在多线程程序里,有时两个或更多的线程共享一个相同的实例变量。考虑效率的问题,每个线程可以自己保存该共享变量的私有拷贝。

    实际的(或主要的)变量副本在不同的时候更新,例如当进入synchronized方法时。当这种方式运行良好时,它在时间上会是低效的。在某些情况,真正要紧的是变量主副本的值会体现当前的状态。为保证这点,仅需把变量定义成volatile型,它告诉编译器它必须总是使用volatile变量的主副本(或者至少总是保持一些私有的最新的主副本的拷贝,反之亦然),同时,对主变量的获取必须以简洁次序执行,就像执行私有拷贝一样。

    注意:Java中的volatile或多或少与C/C++中的类似。

    使用instanceof

     

     

    有时,在运行时间内知道对象类型是很有用的。例如,你有一个执行线程生成各种类型的对象,其他线程处理这些对象。这种情况下,让处理线程在接受对象时知道每一个对象的类型是大有裨益的。另一种在运行时间内知道对象的类型是很有用的情形是强制类型转换。Java中非法强制类型转换导致运行时错误。很多非法的强制类型转换在编译时发生。然而包括类层次结构的强制类型转换可能产生仅能在运行时间里被察觉的非法强制类型转换。例如,一个名为A的父类能生成两个子类B和C。这样,在强制B对象转换为类型A或强制C对象转换为类型A都是合法的,但强制B对象转换为C对象(或相反)都是不合法的。因为类型A的一个对象可以引用B或C。但是你怎么知道,在运行时,在强制转换为C之前哪类对象被引用?它可能是A,B或C的一个对象。如果它是B的对象,一个运行时异常被引发。Java  提供运行时运算符instanceof来解决这个问题。

    instanceof运算符具有下面的一般形式:

    object instanceof type

    这里,object是类的实例,而type是类的类型。如果object是指定的类型或者可以被强制转换成指定类型,instanceof将它评估成true,若不是,则结果为false。这样,instanceof是你的程序获得对象运行时类型信息的方法。

    下面的程序说明了instanceof的应用:

    // Demonstrate instanceofoperator.

    class A {

     int i, j;

    }

     

    class B {

     int i, j;

    }

     

    class C extends A {

     int k;

    }

     

    class D extends A {

     int k;

    }

     

    class InstanceOf {

     public static void main(String args[]) {

        A a = new A();

        B b = new B();

        C c = new C();

        D d = new D();

     

        if(a instanceof A) 

          System.out.println("a is instance ofA");

        if(b instanceof B) 

          System.out.println("b is instance ofB");

        if(c instanceof C) 

          System.out.println("c is instance ofC");

        if(c instanceof A) 

          System.out.println("c can be cast toA");

     

        if(a instanceof C) 

          System.out.println("a can be cast toC");

     

        System.out.println();

     

        // compare types of derived types

        A ob;

     

        ob = d; // A reference to d

        System.out.println("ob now refers tod");

        if(ob instanceof D) 

          System.out.println("ob is instanceof D");

     

        System.out.println();

     

        ob = c; // A reference to c

    System.out.println("obnow refers to c");

    if(obinstanceof D) 

          System.out.println("ob can be castto D");

        else

          System.out.println("ob cannot becast to D");

     

        if(ob instanceof A) 

          System.out.println("ob can be castto A");

     

        System.out.println();

     

        // all objects can be cast to Object

        if(a instanceof Object) 

          System.out.println("a may be cast toObject");

        if(b instanceof Object) 

          System.out.println("b may be cast toObject");

        if(c instanceof Object) 

          System.out.println("c may be cast toObject");

        if(d instanceof Object) 

          System.out.println("d may be cast toObject");

      }

    }

    程序输出如下:

    a isinstance of A

    b isinstance of B

    c isinstance of C

    c canbe cast to A

     

    ob nowrefers to d

    ob isinstance of D

     

    ob nowrefers to c

    obcannot be cast to D

    ob canbe cast to A

     

    a maybe cast to Object

    b maybe cast to Object

    c maybe cast to Object

    d maybe cast to Object

    多数程序不需要instanceof运算符,因为,一般来说,你知道你正在使用的对象类型。

    但是,在你编写对复杂类层次结构对象进行操作的通用程序时它是非常有用的。

    strictfp

     

     

    Java 2向Java语言增加了一个新的关键字strictfp。与Java 2同时产生的浮点运算计算模型很轻松的使某些处理器可以以较快速度进行浮点运算例如奔腾处理器。特别指明,在计算过程中,一个不需要切断某些中介值的新的模型产生了。用strictfp来修饰类或方法,可以确保浮点运算(以及所有切断)正如它们在早期Java版本中那样准确。切断只影响某些操作的指数。当一个类被strictfp修饰,所有该类的方法都自动被strictfp修饰。举例来说,下面的程序段告诉Java在MyClass中定义的所有方法都用原始浮点运算模型来计算:

    strictfp class MyClass { //...

    坦白地说,很多程序员从未用过strictfp,因为它只对非常少的问题有影响。

    本  机  方  法

     

     

    尽管这种情况极少发生,你也许希望调用不是用Java语言写的子程序。通常,这样的子程序是CPU的或是你所工作环境的执行代码——也就是说,本机代码。例如,你希望调用本机代码子程序来获得较快的执行时间。或者,你希望用一个专用的第三方的库,例如统计学包。然而,因为Java程序被编译为字节码,字节码由Java运行时系统解释(或动态编译),看起来在Java程序中调用本机代码子程序是不可能的。幸运的是,这个结论是错误的。Java提供了native关键字,该关键字用来声明本机代码方法。一旦声明,这些方法可以在Java程序中被调用,就像调用其他Java方法一样。

    为声明一个本机方法, 在该方法之前用native修饰符, 但是不要定义任何方法体。 例如: 

    public native int meth() ;

    声明本机方法后,必须编写本机方法并要执行一系列复杂的步骤使它与Java代码链接。很多本机方法是用C写的。把C代码结合到Java  程序中的机制是调用Java Native Interface (JNI)。该方法学由Java 1.1创建并在Java 2中增强。(Java 1.0是用不同的方法,该方法已经过时),关于JNI的详尽描述超出了本书的范围。但是下面的描述为多数应用程序提供了足够的信息。

    注意:所需执行的精确的步骤随Java环境和版本的不同而不同,它还依赖于所要实现的本机方法使用的语言。下面的讨论假定在Windows 95/98/NT/2000环境下。所要实现的本机方法是用C写的。理解该过程的最简单的方法是完成一个例子。开始,输入下面的短程序,该程序使用了一个名为test( )的native方法。

    // A simple example that uses anative method.

    public class NativeDemo {

     int i;

     public static void main(String args[]) {

        NativeDemo ob = new NativeDemo();

     

        ob.i = 10;

        System.out.println("This is ob.ibefore the native method:" +

                           ob.i);

        ob.test(); // call a native method

        System.out.println("This is ob.i afterthe native method:" +

                           ob.i);

     }

     // declare native method

    public native void test() ;

     

     // load DLL that contains static method

     static {

        System.loadLibrary("NativeDemo");

     }

    }

    注意test( )方法声明为native且不含方法体。简而言之这是我们用C语言实现的方法。同时注意static块。像本书前面解释过的,一个static块仅在程序开始执行时执行(更为简单的说,当它的类被加载时执行)。这种情况下,它用来加载包含本地执行方法test( )的动态链接库(你不久就会看到怎样创建这个库)。

    该库由loadLibrary()方法加载。loadLibrary()方法是System类的组成单元。它的一般形式为:

    static void loadLibrary(Stringfilename)

    这里,filename是指定保存该库文件名的字符串。在Windows环境下,该文件的扩展名为.DLL。

    写完程序后,编译它生成NativeDemo.class。然后,你必须用javah.exe生成一个文件:

    NativeDemo.h(javah.exe包含在JDK中)。在执行test( )时你要包含NativeDemo.h。为生成NativeDemo.h,用下面的命令:

    javah -jni NativeDemo 该命令生成名为NativeDemo.h的头文件。该文件必须包含在实现test()的C文件中。该命令的输出结果如下:

    /* DO NOT EDIT THIS FILE - it ismachine generated */

    #include <jni.h>

    /* Header for class NativeDemo */

     

    #ifndef _Included_NativeDemo

    #define _Included_NativeDemo

    #ifdef _ _cplusplus

    extern "C" {

    #endif

    /*

     * Class:    NativeDemo

     * Method:   test

     * Signature: ()V

     */

    JNIEXPORT void JNICALLJava_NativeDemo_test

     (JNIEnv *, jobject);

     

    #ifdef _ _cplusplus

    }

    #endif

    #endif

    请特别注意下面一行,该行定义了所要创建的test( )函数的原型:

    JNIEXPORT void JNICALLJava_NativeDemo_test(JNIEnv *, jobject);

    注意函数的名称是Java_NativeDemo_test()。调用本机函数你必须用这样的名字。也就是说,不是生成一个名为test( )的C函数,而是创建一个名为Java_NativeDemo_test()函数。

    加入前缀NativeDemo是因为它把test( )方法作为NativeDemo类的一部分。记住,其他类可以定义它们自己的与NativeDemo定义的完全不同的本地test( )方法。 前缀中包括类名的方法解决了区分不同版本的问题。作为一个常规方法,给本机函数取名,前缀中必须包括声明它们的类名。

    生成了必备的头文件后,可以编写test( )执行文件并把它存在一个名为NativeDemo.c的文件中:

    /* This file contains the Cversion of the

      test() method.

    */

     

    #include <jni.h>

    #include "NativeDemo.h"

    #include <stdio.h>

     

    JNIEXPORT void JNICALLJava_NativeDemo_test(JNIEnv *env, jobject obj)

    {

     jclass cls;

     jfieldID fid;

     jint i;

     

     printf("Starting the native method.\n");

     cls = (*env)->GetObjectClass(env, obj); 

     fid = (*env)->GetFieldID(env, cls, "i", "I");

     

     if(fid == 0) {

        printf("Could not get fieldid.\n");

        return;

     }

     i = (*env)->GetIntField(env, obj, fid);

     printf("i = %d\n", i);

     (*env)->SetIntField(env, obj, fid, 2*i);

     printf("Ending the native method.\n");

    }

    注意此文件包含具有接口信息的jni.h文件。该文件由你的Java  编译器提供。头文件NativeDemo.h预先已由javah创建。该函数中,GetObjectClass()方法用来获得一个含有NativeDemo类信息的C结构。GetFieldID( )方法返回一个包含该类域名“i”信息的C结构。GetIntField()检索该域原来的值。SetIntField( )存储该域的一个更新值(别的处理其他数据类型的方法参看文件jni.h)。

    生成NativeDemo.c文件后,必须编译它生成一个DLL文件。用微软C/C++编译器来做,使用下面的命令行:

    Cl /LD NativeDemo.c

    它生成了一个名为NativeDemo.dll的文件。该步骤完成,你可以执行Java  程序。该程序输出如下:

    This is ob.i before the nativemethod: 10

    Starting the native method.

    i = 10

    Ending the native method.

    This is ob.i after the nativemethod: 20

    注意:使用native的特殊环境是依赖于实现和环境的。而且,与JAVA代码接口的指定方式必须改变。你必须仔细考虑完成你Java开发系统文件的本机方法。

     

    使用本机方法的问题

     

     

    本机方法看起来提供巨大承诺,因为它们使你有权使用已经存在的库程序,而且使快速执行成为可能。但是本机方法同样引入了两个重大问题:

    · 潜在的安全隐患  因为本机方法执行实际的机器代码,它有权使用主机系统的任何资源。也就是说,本机代码不受Java执行环境的限制。例如,它可能允许病毒入侵。因为这个原因,小应用程序不能使用本机方法。同样,DLL文件的加载被限制,它们的加载必须经过安全管理器的同意。

    ·  丧失了可移植性   因为本机代码是包含在DLL文件中的,它必须存在于执行Java程序的机器上。而且,因为每一个本机方法都依赖于CPU和操作系统,每一个DLL文件在本质上都是不可可移植性的。这样,一个运用本机方法的Java程序只能在一个已经安装了可兼容的DLL的机器上运行。

    本机方法的使用是受限的,因为它使Java程序丧失了可移植性且造成重大安全隐患。



    实践问题:

     

    1. 对比控制台读写和文件读写,以及键盘输入字符的原理;思考计算机是怎样存储并显示文件和字符的?

    2. 思考水库中的水是怎么流入家庭的水管里的;这种流水和本章中的流的概念有何异同?

     



    小结:

     

     

    在本章中,我们主要学习了:

     

    u      流的概念;

    u      读写文件及读写控制台;

    u      其他与流处理相关的关键字

     



    英语词汇:

     

     

    英文                    全文                                  中文

     

    Applet     Applet               小应用程序言

    AWT        Abstract Window Toolkit     抽象窗口工具包

    IOException          IOException                        IO异常

    InputStream          InputStream                        输入流

    OutputStream        OutputStream                      输出流

    BufferedReader    BufferedReader                  缓冲输入流

    Graphics        Graphics                      图形类型

    Transient              Transient                     修饰符,瞬态的 短暂的

    Volatile          Volatile                 修饰符,易变的, 反复无常的

    Instanceof             Instanceof             二元操作符,测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。

    Strictfp                 Strict Float Point                 精确浮点

     

     



    练习项目:

     

     

    包龙兴到街上算命,算命的老先生只问了他的生辰八字;就能知道他的性格、脾气等简单信息;试着使用本章所学知识实现本案例?

    展开全文
  • 第五章 微型计算机输入输出接口

    千次阅读 2012-11-17 20:16:54
    3、复合输入输出设备 按照设备的功效:  1、人机交互设备;2、数据存储设备;3、媒体输入输出设备;4、数据采集与设备控制 与主机交换信号  1、数据信号;2、控制信号;3、状态信号(ready、busy、error)
  • 一个非常完全的waveOut程序,包括了一个waveOut类和使用类的范例,这个范例获得Windows下所有的wave输入输出设备的名称以及属性(22KB)
  • VB6操作麦克风和音箱实现声音输入输出,VB声音控制源码下载,打开程序后,将自动获取到声音驱动设备,波形图上方的滑块,可控制音量大小,下面的波形图会根据声音的大小自动变化,程序支持全屏的波形图,双击波形图...
  • 基于HDMI的视频流输入输出

    千次阅读 2019-03-11 11:10:48
    本实验基于ECE-CV K7-75T FPGA开发板实现。软件使用Vivado 2018.1。基于HDMI的视频流输入输出实验1 HDMI概述HDMI高清多媒体界面(英语:High De...
  • 基于HDMI的视频流输入输出实验

    千次阅读 2019-08-21 16:58:36
    基于HDMI的视频流输入输出实验 1 HDMI概述 HDMI高清多媒体界面(英语:High Definition Multimedia Interface)是一种全数字化视频和声音发送接口,可以发送未压缩的音频及视频信号。HDMI可用于机顶盒、DVD播放机...
  • 学习目标:对输入输出系统有一个较清晰的认识,加深对整机工作的理解。 一、输入输出系统概况 输入输出系统的发展大致可分为4个阶段。 1.早期阶段 早期的I/O设备种类较少,I/O设备与主存交换信息都必须通过CPU。 2....
  • 概述1.1 输入输出系统的发展概述1.2 输入输出系统的组成1.3 I/O设备与主机的联系方式1.4 I/O设备与主机信息传送的方式2.I/O设备3.I/O接口4.程序查询方式5.程序中断方式6.DMA方式 1.概述 1.1 输入输出系统的发展概述 ...
  • 欧胜微电子有限公司(Wolfson Microelectronics)面向便携式多媒体设备推出立体声编解码器,可提供高质量的音频性能,同时具有低功耗。 WM8983能够赋予手机灵活的、新的应用模式。这些模式包括在收听MP3或FM收音机的...
  • 输入输出系统(一) - 概述(一)

    千次阅读 2017-11-26 15:26:12
    Abstract:计算机组成原理这部分内容全部都是来自于:哈工大计算机组成原理刘宏伟。用的教材是唐朔飞教授的。 后面不再说明。...输入输出系统时计算机中种类最多, 功能最多, 结构最复杂, 构成也最复杂的部分
  • 05计组课后习题:输入输出系统

    千次阅读 2019-11-24 13:27:13
    此外,点阵针式打印机是属于击打式打印机,可以逐字打印也可以逐行打印,喷墨打印机只能逐字打印,激光打印机据页式输出设备,后两者都属于非击打式打印机。 不同种类的打印机其性能和价格差别很大,用户可以根据...
  • 声音信息在计算机中以文件的形式存储 三个基本功能 模拟声音信号的输入输出功能数模转换D/A模数转换 音乐合成发音功能 混音器Mixer功能和数字声音效果处理器DSP功能 ;7.1.2 声卡的分类;按接口类型分;7.1.4 声卡的...
  • 海思多媒体处理平台(MPP)分为:视频输入(VI),视频处理(VPSS),视频编码(VENC),视频解码(VDEC),视频输出(VO)、视频侦测分析(VDA),音频输入(AI),音频输出(AO),音频编码(AENC),音频解码(ADEC),区域管理(REGION)等模块....
  • 本文就目前常见的相机输出接口CVBS、VGA、DVI、HDMI、SDI、Camera Link、HS-LINK、CoaXPress这8种类型做出一一介绍。 1.CVBS CVBS是Composite Video Broadcast Signal的缩写,中文翻译为复合视频广播信号。这是最...
  • 多媒体播放声音多路输出

    千次阅读 2012-06-20 17:06:32
    directshow做的播放器,需要向所有的声卡输出,在graph图中,可加入多个directsound filter,每个输出设备一个,同infinite pin tee filter 连接。 这种方式存在弊端,就是数据同步会导致卡顿现象,音视频同步...
  • 适用的便携式产品包括个人数字助理、多媒体播放机、测量仪表、医疗设备以及移动电话等。    便携式电子产品厂商不断为产品添加各种独特功能,例如量身订造的键盘或特别的灯光效果,因此,有关产品必须采用更加...
  • 该四路输出设备是为当今便携式设备中使用的系统核心、输入/输出 (I/O)、辅助设备以及 SDRAM、NAND 闪存或 Secure Digital (SDIO) 等外部存储器提供所需电压的理想选择。MIC2811/21 目前批量供应,1000件起售,单价为...
  • 海思多媒体处理平台(MPP)分为:视频输入(VI),视频处理(VPSS),视频编码(VENC),视频解码(VDEC),视频输出(VO)、视频侦测分析(VDA),音频输入(AI),音频输出(AO),音频编码(AENC),音频解码(ADEC),区域管理(REGION)等模块....
  • 多媒体的发展历程

    2013-11-19 22:56:24
    从过去用纸带和卡片的有孔或无孔表示信息,纸带和卡片机是主要的的输入输出设备,直到20世纪50年代到70年代,出现了高级程序设计语言,人们可以用文字编写源程序输入计算机,计算机处理的结果也可以用文字表示输出。...
  • DAQ 工具箱中假设输入输出设备的顺序相同。 如果您在控制面板中的 windows 多媒体设置中有多个播放/录制设备可用,并且您更改了顺序,则如果两个列表不匹配,则会出现问题。 数据采集​​工具箱假定输出与输入...
  • 简述多媒体系统的组成 多媒体系统由多媒体硬件系统和多媒体软件系统组成多媒体 硬件系统主要由多媒体计算机多媒体存储设备多媒体输入 /输出 设备和多媒体接口设备组成多媒体软件系统主要由多媒体操作系 统多媒体驱动...
  • 1、1、 下列硬件设备中,多媒体硬件系统必须包括的设备中不含_D_____。 A.计算机最基本的硬件设备 B.多媒体通信传输设备 ...音频输入输出和处理设备 D.CD-ROM --- 是多媒体计算机常有的,但不是必须的
  • 多媒体技术基本概念汇总

    千次阅读 2015-07-28 00:05:20
    多媒体技术这门课中我们将会学到如何使用音频,视频,图片等资源来进行处理。下面的资料是我在大学阶段整理的多媒体技术的基本概念,希望对大家有所帮助。 多媒体技术期末知识点汇总 多媒体技术的主要特性有:(1)...
  • 第9章 计算机多媒体技术单选题 其实我所给的这些典型题目就是期末考试题或统考题因此必做参考答案在另一个Word文档中 ...音频输入输出和处理设备 D.CD-ROM --- 一般多媒体计算机都配有CD-ROM但不是必须的 [解析]略 以

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,719
精华内容 11,487
关键字:

常见的多媒体输入输出设备