在main.xml 中:
<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="auto_fit" android:verticalSpacing="15dp" android:horizontalSpacing="12dp" android:columnWidth="95dp" android:stretchMode="columnWidth" android:gravity="center" />
然后在item.xml给item布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" > <ImageView android:id="@+id/apps_image" android:layout_width="48dip" android:layout_height="48dip" android:icon="@drawable/ic_launcher" /> <TextView android:id="@+id/apps_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:maxEms="5" android:text="good" /> </LinearLayout>
在Activity中显示
public class UnloadingActivity extends Activity { // 用来记录应用程序的信息 List<AppsItemInfo> list; private GridView gridview; private PackageManager pManager; private String uninstallPackage; // int state; // int mNum; // final static int PROGRESS_DIALOG = 0; // ProgressThread progressThread; // ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); this.setContentView(R.layout.main); // 取得gridview gridview = (GridView) findViewById(R.id.gridview); // 获取图片、应用名、包名 pManager = UnloadingActivity.this.getPackageManager(); List<PackageInfo> appList = getAllApps(UnloadingActivity.this); list = new ArrayList<AppsItemInfo>(); for (int i = 0; i < appList.size(); i++) { PackageInfo pinfo = appList.get(i); AppsItemInfo shareItem = new AppsItemInfo(); // 设置图片 shareItem.setIcon(pManager .getApplicationIcon(pinfo.applicationInfo)); // 设置应用程序名字 shareItem.setLabel(pManager.getApplicationLabel( pinfo.applicationInfo).toString()); // 设置应用程序的包名 shareItem.setPackageName(pinfo.applicationInfo.packageName); list.add(shareItem); } // 设置gridview的Adapter gridview.setAdapter(new baseAdapter()); // 点击应用图标时,做出响应 gridview.setOnItemClickListener(new ClickListener()); } public static List<PackageInfo> getAllApps(Context context) { List<PackageInfo> apps = new ArrayList<PackageInfo>(); PackageManager pManager = context.getPackageManager(); // 获取手机内所有应用 List<PackageInfo> packlist = pManager.getInstalledPackages(0); for (int i = 0; i < packlist.size(); i++) { PackageInfo pak = (PackageInfo) packlist.get(i); // 判断是否为非系统预装的应用程序 // 这里还可以添加系统自带的,这里就先不添加了,如果有需要可以自己添加 // if()里的值如果<=0则为自己装的程序,否则为系统工程自带 if ((pak.applicationInfo.flags & pak.applicationInfo.FLAG_SYSTEM) <= 0) { // 添加自己已经安装的应用程序 apps.add(pak); } } return apps; } private class baseAdapter extends BaseAdapter { LayoutInflater inflater = LayoutInflater.from(UnloadingActivity.this); @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } public final class ViewHolder { private ImageView icon; private TextView label; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder; if (convertView == null) { // 使用View的对象itemView与R.layout.item关联 convertView = inflater.inflate(R.layout.item, null); holder = new ViewHolder(); holder.icon = (ImageView) convertView .findViewById(R.id.apps_image); holder.label = (TextView) convertView .findViewById(R.id.apps_textview); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.icon.setImageDrawable(list.get(position).getIcon()); holder.label.setText(list.get(position).getLabel().toString()); return convertView; } } // 当用户点击应用程序图标时,将对这个类做出响应 private class ClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { AppsItemInfo app = list.get(position); uninstallPackage = app.packageName; AppUtils.uninstallApk(UnloadingActivity.this, uninstallPackage); } } // 自定义一个 AppsItemInfo 类,用来存储应用程序的相关信息 private class AppsItemInfo { private Drawable icon; // 存放图片 private String label; // 存放应用程序名 private String packageName; // 存放应用程序包名 public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } } }
随着嵌入式技术应用领域的不断扩展,对嵌入式系统的要求越来越高,而作为嵌入式系统核心的微处理器也面临日益严竣的挑战。ARM公司从成立以来,一直以知识产权(IP,Intelligence Property)提供者的身份出售知识产权,在32位RISC CPU开发领域中不断取得突破,其设计的微处理器结构已经从v3发展到现在的v7。
引 言
Cortex系列处理器是基于ARMv7架构的,分为Cortex-M、Cortex-R和Cortex-A三类。ARM系列微处理器的核心及体系结构如表1所列。
1 ARM Cortex处理器技术特点
ARMv7架构是在ARMv6架构的基础上诞生的。该架构采用了Thumb-2技术,它是在ARM的Thumb代码压缩技术的基础上发展起来的,并且保持了对现存ARM的完整的代码兼容性。Thumb-2技术比纯32位代码少使用31%的内存,减小了系统开销。
同时能够提供比已有的基于Thumb技术的高出38%的性能。ARMv7架构还采用了NEON技术,将DSP和媒体处理能力提高了近4倍,并支持改良的浮点运算,满足下一代3D图形、游戏物理应用以及传统嵌入式控制应用的需求。此外,ARMv7还支持改良的运行环境,以迎合不断增加的JIT(Just In Time)和DAC(DynamicAdaptive Compilation)技术的使用。
在与早期的ARM处理器软件兼容性方面,ARMv7架构在设计时充分考虑到了。ARM Cortex-M系列支持Thumb-2指令集(Thumb指令集的扩展集),可以执行所有已存的为早期处理器编写的代码。通过一个前向的转换方式,为ARM Cortex-M系列处理器所写的用户代码可以与ARM Cortex-R系列微处理器完全兼容。
ARMCortex-M系列系统代码(如实时操作系统)可以很容易地移植到基于ARM Cortex-R系列的系统上。ARMCortex-A和Cortex-R系列处理器还支持ARM 32位指令集,向后完全兼容早期的ARM处理器,包括从1995年发布的ARM7TDMI处理器到2002年发布的ARMll处理器系列。图1为v5~v7架构的处理器技术比较。由于应用领域的不同,基于v7架构的Cortex处理器系列所采用的技术也不相同。
在命名方式上,基于ARMv7架构的ARM处理器已经不再延用过去的数字命名方式,而是冠以Cortex的代号。基于v7A的称为"Cortex-A系列",基于v7R的称为"Cortex-R系列",基于v7M的称为"Cortex-M3"。
2 ARM Cortex-M3处理器技术特点
ARM Cortex-M3处理器是为存储器和处理器的尺寸对产品成本影响极大的各种应用专门开发设计的,其结构如图2所示。它整合了多种技术,减少使用内存,并在极小的RISC内核上提供低功耗和高性能,可实现由以往的代码向32位微控制器的快速移植。ARM Cortex-M3处理器是使用最少门数的ARM CPU,相对于过去的设计大大减小了芯片面积,可减小装置的体积或采用更低成本的工艺进行生产,仅33 000门的内核性能可达1.2DMIPS/MHz。此外,基本系统外设还具备高度集成化特点,集成了许多紧耦合系统外设,合理利用了芯片空间,使系统满足下一代产品的控制需求。
ARM Cortex-M3处理器结合了执行Thumb-2指令的32位哈佛微体系结构和系统外设,包括Nested Vec-tored Interrupt Controller和Arbiter总线。该技术方案在测试和实例应用中表现出较高的性能:在台机电180 nm工艺下,芯片性能达1.2 DMIPS/MHz,时钟频率高达100 MHz。Cortex-M3处理器还实现了Tail-Chaining中断技术。该技术是一项完全基于硬件的中断处理技术,最多可减少12个时钟周期数,在实际应用中可减少70%中断;推出了新的单线调试技术,避免使用多引脚进行JTAG调试,并全面支持RealView编译器和RealView调试产品。RealView工具向设计者提供模拟、创建虚拟模型、编译软件、调试、验证和测试基于ARMv7架构的系统等功能。
为微控制器应用而开发的Cortex-M3拥有以下性能:
实现单周期Flash应用最优化;
准确快速地中断处理,永不超过12周期,仅6周期tail-chaining(末尾连锁);
有低功耗时钟门控(Clock Cating)的3种睡眠模式;
单周期乘法和乘法累加指令;
ARM Thumb-2混合的16/32位同有指令集,无模式转换;
包括数据观察点和Flash补丁在内的高级调试功能;
原子位操作,在一个单一指令中读取/修改/编写;
1.25 DMIPS/MHz(与O.9DMIPS/MHz的ARM7和1.1 DMIPS/MHz的ARM9相比)。
3 ARM Cortex-R处理器技术特点
ARM Cortex-R系列处理器目前包括ARM Cortex-R4和ARM Cortex-R4F两个型号,主要适用于实时系统的嵌入式处理器。
3.1 ARM Cortex-R4处理器技术特点
Cortex-R4处理器结构如图3所示。该处理器支持手机、硬盘、打印机及汽车电子设计,能协助新一代嵌入式产品快速执行各种复杂的控制算法与实时工作的运算;可通过内存保护单元(MPU,Memory Protection Unit)、高速缓存以及紧密耦合内存(TCM,Tightly Coupled Memory)让处理器针对各种不同的嵌入式应用进行最佳化调整,且不影响基本的ARM指令集兼容性。这种设计能够在延用原有程序代码的情况下,降低系统的成本与复杂度,同时其紧密耦合内存功能也能提供更小的规格及更高效率的整合,并带来快速的响应时间。
Cortex-R4处理器采用ARMv7体系结构,让它能与现有的程序维持完全的回溯兼容性,能支持现今建立在全球各地数十亿的系统;并已针对Thumb-2指令进行最佳化设计。此项特性带来很多的利益,其中包括:更低的时钟速度所带来的省电效益;更高的性能将各种多功能特色带人移动电话与汽车产品的设计;更复杂的算法支持更高性能的数码影像与内建硬盘的系统。运用Thumb-2指令集,加上RealView开发套件,使芯片内部存储器的容量最多得以降低30%,大幅降低系统成本,其速度比在ARM946E-S处理器所使用的Thumb指令集高出40%。由于存储器在芯片中的占用空间愈来愈多,因此这项设计将大幅节省芯片容量,让芯片制造商运用这款处理器开发各种SoC(System on a Chip)器件。
相比于前几代的处理器,Cortex-R4处理器高效率的设计方案,使其能以更低的时钟达到更高的性能;经过最佳化设计的Artisan Metro内存,则进一步降低嵌入式系统的体积与成本。处理器搭载一个先进的微架构,具备双指令发送功能,采用90 nm工艺并搭配Artisan Advantage程序库的组件,底面积不到1 mm2,耗电量低于0.27mW/MHz,并能提供超过600 DMIPS的性能。
Cortex-R4处理器在各种安全应用上加入容错功能和内存保护机制,支持最新版OSEK实时操作系统;支持RealView Develop系列软件开发工具、RealView Create系列ESL工具与模块,以及Core Sight除错与追踪技术,协助设计者迅速开发各种嵌入式系统。
3.2 ARM Cortex-R4F处理器技术特点
Cortex-R4F处理器结构如图4所示。该处理器拥有针对汽车市场而开发的各项先进功能,包括自动除错功能、可相互连结的错误侦测机制,以及可选择优化的浮点运算单元(FPU,Floating-Point Unit)。ECC技术能监控内存存取作业,侦测并校正各种错误。当发生内存错误时,ECC逻辑除通报错误并停止系统运作外,还会加以校正。
它还拥有Cortex-R4系列的各项先进功能,能够透过高效能内存保护单元、高速缓存,以及紧密耦合内存,使处理器能针对各种不同的应用进行最佳化调整;同时将传统处理器中的错误侦测功能延伸至整个SoC中,系统会不断地扫描先前侦错的资料,以提升系统的可靠度。基于对安全性能的重视,Cortex-R4F处理器特别搭载了高分辨率内存保护机制,能严密控制独立的软件作业。
Cortex-R4F处理器中执行浮点运算的FPU,提供胜过固定小数点操作数的动态范围及精准度。该FPU与ARM其他处理器核心之间的FPU均维持回溯兼容性,并针对各种汽车应用常见的单精度处理作业进行优化。使用单倍精度格式,而非双倍精度的数值资料,不仅能将数据处理速度提升至2倍,更能维持必要的精度以提高SoC设计的效率。
Cortex-R4F处理器采用一套具备双指令发送功能的先进微架构,透过ARM Artisan Advantage程序库中针对90 nm工艺的优化,达到超过800 DMIPS的性能水准。Level 1内存松散的时序设计,使组件能使用高密度、低功耗的RAM,使在总成本中占有高比重的内存,能像处理器逻辑一样拥有节省空间的优势。在90 nm工艺下,占用空间不到1 mm2,且耗电量不到0.27 mW/MHz,有效地协助系统开发者降低成本与功耗。
该处理器采用ARMv7ISA架构,能与已被全球数十亿台系统所采用的ARM程序代码维持回溯兼容性,并针对Thumb-2指令集进行最优化设计。运用Thumb-2指令,搭配ARM RealView开发套件,使芯片内部存储器的容量最大能缩减30%,大幅降低系统成本。此外,相较于内建在ARM946E-S处理器的旧版Thumb指令集,新技术能够提高40%的工作效能。
4 ARM Cortex-A8处理器技术特点
ARM Cortex-A8处理器是一款适用于复杂操作系统及用户应用的应用处理器,其结构如图5所示。支持智能能源管理(IEM,Intelligent Energy Manger)技术的ARM Artisan库以及先进的泄漏控制技术,使得Cortex-A8处理器实现了非凡的速度和功耗效率。在65 nm上艺下,ARM cortex-A8处理器的功耗不到300 mW,能够提供高性能和低功耗。它第一次为低费用、高容量的产品带来了台式机级别的性能。
ortex-A8处理器是第一款基于下一代ARMv7架构的应用处理器,使用了能够带来更高性能、更低功耗和更高代码密度的Thumb-2技术。它首次采用了强大的NEON信号处理扩展集,为H.264和MP3等媒体编解码提供加速。
Cortex-A8的还包括Jazelle-RCTJava加速技术,对实时(JIT)和动态调整编译(DAC)提供最优化,同时减少内存占用空间高达3倍。该处理器配置了先进的超标量体系结构流水线,能够同时执行多条指令,并且提供超过2.0 DMIPS/MHz的性能。处理器集成了一个可调尺寸的二级高速缓冲存储器,能够同高速的16 KB或者32 KB一级高速缓冲存储器一起工作,从而达到最快的读取速度和最大的吞吐量。新处理器还配置了用于安全交易和数字版权管理的Trust Zone技术,以及实现低功耗管理的IEM功能。
Cortex-A8处理器使用了先进的分支预测技术,并且具有专用的NEON整型和浮点型流水线进行媒体和信号处理。在使用小于4 mm2的硅片及低功耗的65 nm工艺的情况下,Cortex-A8处理器的运行频率将高于600MHz(不包括NEON追踪技术和二级高速缓冲存储器)。在高性能的90 nm和65 nm工艺下,Cortex-A8处理器运行频率最高可达1 GHz,能够满足高性能消费产品设计的需要。
结 语
这些新的ARM Cortex处理器系列都是基于ARMv7架构的产品,从尺寸和性能方而来看,既有少于33 000个门电路的ARM Cortex-M系列,也有高性能的ARMCortex-A系列。
其中,ARM Cortex-A系列是针对日益增长的,运行包括Linux、Windows,CE和Symbian操作系统在内的消费者娱乐和无线产品设计的;ARM Cortex-R系列针对的是需要运行实时操作系统来进行控制应用的系统,包括汽车电子、网络和影像系统;ARM Cortex-M系列则是为那些对丌发费用非常敏感同时对性能要求小断增加的嵌入式应用(如微控制器、汽车车身控制系统和各种大型家电)所设计的。随着在各种不同领域应用需求的增加,微处理器市场也在趋于多样化。为了适应市场的发展变化,基于ARMv7架构的ARM处理器系列将不断拓展自己的应用领域
原文地址:http://kinglaw05.blog.163.com/blog/static/59683314200893033226638/
一、File类
File类的对象主要用来获取文件本身的一些信息。例如文件所在的目录、文件的长度、文件读写权限等,不涉及对文件夹的读写操作。创建一个File对象的构造方法有3个:
■File(String filename);
■File(String directoryPath,String filename);
■File(File f,String filename);
其
中,filename是文件名,directoryPath是文件的路径,f是指定成一个目录的文件。使用File(String
filename)创建文件时,该文件被认为是与当前应用程序在同一目录中。由于JSP引擎是在bin下启动执行的。所以该文件被认为在bin目录中。
获取文件的属性
使用File类的下列方法获取文件本身的一些信息:
■public String getName() 获取文件的名字
■public boolean canRead() 判断文件是否是可读的
■public boolean canWrite() 判断文件是否是可被写的
■public boolean exits() 判断文件是否存在
■public long length() 获取文件的长度(单位是字节)
■public String getAbsolutePath() 获取文件的绝对路径
■public String getParent() 获取文件的父目录
■public boolean isFile() 判断文件是否是一个正常文件,而不是目录
■public boolean isDirectory() 判断文件是否是一个目录
■public boolean isHidden() 判断文件是否是隐藏文件
■public long lastModified() 获取文件最后修改的时间
创建目录
File对象调用方法public boolean mkdir()创建一个目录,如果创建成功就返回true,否则返回false(如果该目录已经存在将返回false)。
列出目录中的文件
如果File对象是一个目录,那么该对象可以调用下述方法列出该目录下的文件和子目录:
■public String[] list() 用字符串形式返回目录下的全部文件
■public String[] listFiles() 用File对象形式返回目录下的全部文件
列出指定类型的文件
我们有时需要列出目录下指定类型的文件。可以使用File对象的下述两个方法,列出指定类型的文件。
■public String[] list(FilenameFilter obj) 该方法用字符串形式返回目录下的指定类型的所有文件
■public File[] listFiles(FilenameFilter obj) 该方法用File对象返回目录下的指定类型的所有文件
FilenameFilter是一个接口,该接口有一个方法:
public boolean accept(File dir,String name);
当向list方法传递一个实现该接口的对象时,list方法将在列出文件时,让该文件调用accept方法检查该文件是否符合accept方法指定的目录和文件名字的要求。
删除文件和目录
File对象调用方法 public boolean delete() 可以删除当前对象代表的文件或目录。如果File对象表示的是一个目录,则该目录必须是一个空目录,删除成功将返回true。
二、使用字节流读写文件
JAVA的I/O流提供一条通道程序,可以使用这条通道把源中的数据送给目的地。输入流的指向称做源,程序从指向源的输入流中读取源中的数据。输出流的指向是数据要去的一个目的地,程序通过向输出流中写入数据把信息传递到目的地。如图:
java.io包提供大量的流类。所有字节输入流类都是InputStream(输入流)抽象类的子类,而所有字节输出流类都是OutputStream(输出流)抽象类的子类。
InputStream类的常用方法:
■int read() 输入流调用该方法从源中读取单个字节的数据,该方法返回字节值(0~255之间
的一个整数)。如果未读了字节就返回 -1。
■int read(byte b[]) 输入流调用该方法从源中试图读取b,length个字节到b中,返回实际读取的字节
数目。如果到达文件末尾则返回 -1。
■int read(byte b[],int off,int len) 输入流调用该方法从源中试图读取len个字节到b中,并返回实际读取的字节数
目。如果到达文件的末尾,则返回 -1。参数off指定从字节数组某个位置开始存
放读取的数据。
■void close() 输入流调用该方法关闭输入流。
■long skip(long numBytes) 输入流调用该方法跳过numBytes个字节,并返回实际跳过的字节数目。
OutputStream类的常用方法:
■void write(int n) 输出流调用该方法向输出流写入单个字节。
■void write(byte b[]) 输出流调用该方法向输出流写入一个字节数组。
■void write(byte b[],int off,int len) 从给定字节数组中起始于偏移量off处取len个字节写到输出流。
■void close() 关闭输出流。
FileInputStream类
FileInputStream类是从InputStream类中派生出来的简单输入类。该类的所有方法都是从InputStream类继承来的。它有两个构造方法:
■FileInputStream(String name)
■FileInputStream(File file)
第一个构造方法使用给定的文件名name创建一个FileInputStream对象。第二个构造方法使用File对象创建FileInputStream对象。参数name和file指定的文件称做输入流的源。输入流通过调用read方法读出源中的数据。
例如,为了读取一个名为abc.dat的文件,建立一个文件输入流对象,如下所示:
FileInputStream istream = new FileInputStream("abc.dat");
文件输入流构造方法的另一种格式是允许使用文件对象来指定要打开哪个文件。如下所示:
File f = new File("abc.dat");
FileInputStream istream = new FileInputStream(f);
FileOutputStream类
FileOutputStream类提供了基本的文件写入能力。构造方法有:
■FileOutputStream(String name)
■FileOutputStream(File file)
第
一个构造方法使用给定的文件名name创建一个FileOutputStream对象。第二个构造方法使用File对象创建
FileOutputStream对象。参数name和file指定的文件称做输出流的目的地,通过向输出流写入数据把信息传递到目的地。创建输出流对象
可能发生IOException异常,必须在try,catch语句块中创建输出流对象。
BufferedInputStream类和BufferedOutputStream类
为
了提高读写的效率,FileInputStream流经常和BufferedInputStream流配合使用,FileOutputStream流经常
和BufferedOutputStream流配合使用。BufferedInputStream类的一个常用的构造方法是:
BufferedInputStream(InputStream in)
该构造方法创建缓存输入流,该输入流的指向是一个输入流,当我们要读取一个文件,如abc.txt时,可以先建立一个指向该文件的文件输入流:
FileInputStream in = new FileInputStream("abc.txt");
然后再创建一个指向文件输入流in的输入缓存流(就好像把两个输入水管接在一起):
BufferedInputStream buffer = new BufferedInputStream(in);
这时,我们就可以让buffer调用read方法读取文件的内容。buffer在读取文件的过程中会进行缓存处理,提高读取的效率。同时,当要向一个文件,如def.txt,写入字节时,可以先建立一个指向该文件的文件输出流:
FileOutputStream out = new FileOutputStream("def.txt");
然后再创建一个指向输出流out的输出缓存流:
BufferedOutputStream buffer = new BufferedOutputStream(out);
这时,buffer调用write方法向文件写入内容时会进行缓存处理,提高写入的效率。需要注意的是,写入完毕后,须调用flush方法将缓存中的数据存入文件。
三、使用字符流读写文件
字节流不能直接操作
Unicode字符,所以JAVA提供了字符流。由于汉字在文件中占用2个字节,如果使用字节流,读取不当会出现乱码现象。采用字符流可以避免这个现象。
在Unicode字符中,一个汉字被看作一个字符。所有字符输入流类都是Reader抽象类的子类,所有字符输出流类都是Writer抽象类的子类。
Reader类中的常用方法:
■int read() 调用该方法从源中读取一个字符,该方法返回一个整数(0~65535之间的一个
整数,Unicode字符值),如果未读出字符就返回-1
■int read(char b[]) 调用该方法从源中读取b。length个字符到字符数组b,返回实际读取的字符数
目。如果到达文件的末尾,则返回-1
■int read(char b[],in off,int len) 调用该方法从源中读取len个字符并存放到字符数组b中,返回实际读取的字符
数目。如果到达文件的末尾,则返回-1。其中off参数指定read方法从字符数组
b中的什么地方存放数据。
■void close() 关闭输入流
■long skip(long numBytes) 调用该方法跳过numBytes个字符,并返回实际跳过的字符数目
Writer类中的常用方法:
■void write(int n) 向输出流写入一个字符
■void write(byte b[]) 向输入流写入一个字符数组
■void write(byte b[],int off,int length) 从给定数组中起始于偏移量off处取len个字符写到输出流
■void close() 关闭输出流
FileReader类
FileReader类是从Reader类中派生出来的简单输入类。该类的所有方法都是从Reader类继承来的。构造方法如下:
FileReader(String name)
FileReader(File file)
第一个构造方法使用给定的文件名name创建一个FileReader对象。第二个构造方法使用File对象创建FileReader对象。参数name和file指定的文件称做输入流的源。输入流通过调用read方法读出源中的数据。
FileWriter类
FileWriter类的构造方法:
FileWriter(String name)
FileWriter(File file)
第
一个构造方法使用给定的文件名name创建一个FileWriter对象。第二个构造方法使用File对象创建FileWriter对象。参数name和
file指定的文件称做输出流的目的地,通过向输出流中写入数据把信息传递到目的地。创建输入、输出流对旬会发生IOException异常,必须在
try,catch语句块中创建输入、输出流对象。
BufferedReader类和BufferedWriter类
为
了提高读写的效率,FileReader流经常和BufferedReader流配合使用,FileWriter流经常和BufferedWriter流
配合使用。BufferedReader流还可以使用方法String
readLine()读取一行,BufferedWriter流还可以使用方法void write(String s,int off,int
length)将字符串s的一部分写入文件,使用方法newLine()向文件写入一个行分隔符。
四、回压字符流
PushbackReader类创建的对
象称为回夺字符流。回压流可以使用unread(char
ch)将一个字符回压到该流中,被回压的字符是该回压流紧接着再调用read()方法时最先读出的字符。回压流可以用来监视读出的信息,当读出一个不需要
的信息时,可以不处理该信息,而将需要的信息回压,然后再读出回压的信息。该类的构造方法是:
PushbachReader(Reader in);
当
我们使用前面讲的字节输入流或字符输入流把JSP文件或超文本文件发送给客户时,客户的浏览器将解释运行超文本标记,客户无法看见原始的超文本文件或
JSP文件。我们可以使用回压流技术读取原始的网页文件。当读取到"<"符号时,将"<"回压,读取到">"符号时,
将">"回压。可能有人会问,为什么"<"要回压"<",而">"要回压">",这是因为在html代
码里,&TL代表<,而>代表>,具体可以看下表
五、数据流
DataInputStream类和DataOutputStream类创建的对象分别被称为数据输入流和数据输出流。它们允许程序按着与机器无关的风格读取JAVA原始数据。也就是说,当我们读取一个数值时,不必再关心这个数值应当是多少个字节。它们的构造方法为:
DataInputStream(InputStream in) 将创建的数据输入流指向一个由参数in指定的输入流,以便从后者读取数据
(按着与机器无关的风格读取。)
DataOutputStream(OutputStream out) 将创建的数据输出流指向一个由参数out指定的输出流,然后通过这个数
据输出流把JAVA数据类型的数据写到输出流out。
DataInputStream类和DataOutputStream类的部分方法
方法
描述
方法
描述
close()
关闭流
readUTF()
读取一个 UTF 字符串
readBoolean()
读取一个布尔值
skipBytes(int n)
跳过给定数量的字节
readByte()
读取一个字节
writeBoolean(Boolean v)
把一个布尔值作为单字节写入
readChar()
读取一个字符
writeBytes(String s)
写入一个字符串
readDouble()
读取一个双精度浮点值
writeChars(String s)
写入字符串
readFloat()
读取一个单精度浮点值
writeDouble(double v)
写入一个双精度浮点值
readInt()
从文件中读取一个 int 值
writeFloat(float v)
写入一个单精度浮点值
readlong()
读取一个长型值
writeInt(int v)
写入一个 int 值
readShort()
读取一个短型值
writeLong(long v)
写入一个长型值
ReadUnsignedByte()
读取一个无符号字节
writeShort(int v)
写入一个短型值
ReadUnsignedShort()
读取一个无符号短型值
writeUTF(String s)
写入一个 UTF 字符串
六、对象流
ObjectInputStream类和
ObjectOutputStream类分别是InputStream类和OutpuStream类的子类。ObjectInputStream类和
ObjectOutputStream类创建的对象分别称为对象输入流和对象输出流。对象输出流使用writeObject(Object
obj)方法将一个对象obj写入到一个文件,对象输入流使用readObject()方法读取一个对象到程序中。二者的构造方法为:
ObjectInputStream(InputStream in);
ObjectOutputStream(OutputStream out);
小插曲:要存储数据,可以使用散列表这种数据结构。要创建散列表对象,可以使用java.util包中的Hashtable类,该类的常用方法有:
■public Hashtable() 创建具有默认容量和装载因子为0.75的散列表。
■public Hashtable(int itialCapacity) 创建具有指定容量和装载因子为0.75的散列表。
■public Hashtable(int initialCapacity,float loadFactor) 创建具有默认容量和指定装载因子的散列。
■public void clear() 清空散列表。
■public boolean contains(Object o) 判断散列是否含有元素o。
■public Object get(Object key) 获取散列中具有关键字key的数据项。
■public boolean isEmpty() 判断散列表是否为空。
■public Object put(Object key,Object value) 向散列表添加数据项value并把关键字key关联到value。
■public Object remove(Object key) 删除关键字是key的数据项。
■public int size() 获取散列表中关键字的数目。
■public boolean containsKey(Object key) 判断散列是否使用了关键字key。
使用上述的get方法可以从散列表中检索某个数据。我们还可以借助Enumeration对象实现遍历散列表。一个散列表可以使用elements()方法获取一个Enumeration对象,后者使用nextElement()方法遍历散列表。
七、RandomAccessFile类
RandomAccessFile
类创建的流与之前的输入、输出流不同。RandomAccessFile类既不是输入流类InputStream类的子类,也不是输出流类
OutputStream类的子类。RandomAccessFile流的指向既可以作为源也可以作为目的地。换句话说,当我们想对一个文件进行读写操作
时,我们可以创建一个指向该文件的RandomAccessFile流,这样既可以从这个流中读取这个文件的数据,也可以通过这个流给这个文件写入数据。
它有两个构造方法:
■RandomAccessFile(String name,String mode)
■RandomAccessFile(File file,String mode)
参数name用来确定一个文件名,参数file是一个File对象,二者均是给出创建的流的源(也就是流的目的地)。参数mode取"r"(只读)或"rw"(可读写),决定创建的流对文件的访问权利。创建对象时应捕获IOException异常。
RandomAccessFile类的一些方法如下:
方法
描述
方法
描述
close()
关闭文件
seek()
定位文件指针在文件中的位置
getFilePointer()
获取文件指针的位置
setLength(long newlength)
设置文件的长度
length()
获取文件的长度
skipBytes(int n)
在文件中跳过给定数量的字节
read()
从文件中读取一个字节的数据
write(byte b[])
写 b.length 个字节到文件
readBoolean()
从文件中读取一个布尔值
writeBoolean(Boolean v)
把一个布尔值作为单字节值写入文件
readByte()
从文件中读取一个字节
writeByte(int v)
向文件写入一个字节
readChar()
从文件中读取一个字符( 2 个字节)
writeBytes(String s)
向文件写入一个字符串
readDouble()
从文件中读取一个双精度浮点值( 8 个字节)
writeChar(char c)
向文件写入一个字符
readFloat()
从文件中读取一个单精度浮点值( 4 个字节)
writeChars(String s)
向文件写入一个作为字符数据的字符串
readFully(byte b[])
读 b.length 字节放入数组 b ,完全填满该数组
writeDouble(double v)
向文件写入一个双精度浮点值
readInt()
从文件中读取一个 int 值( 4 个字节)
writeFloat(float v)
向文件写入一个单精度浮点值
readLine()
从文件中读取一个文本行
writeInt(int v)
向文件写入一个 int 值
readlong()
从文件中读取一个长型值( 8 个字节)
writeLong(long v)
向文件写入一个长型 int 值
readShort()
从文件中读取一个短型值( 2 个字节)
writeShort(int v)
向文件写入一个短型 int 值
readUTF()
从文件中读取一个 UTF 字符串
writeUTF(String s)
写入一个 UTF 字符串
八、文件上传
客户通过JSP页面上传文件给服务器时,该JSP页面必须含有File类型的表单,并且表单必须净ENCTYPE的属性值设成multipart/form-data。File类型表单如下所示:
<form action="/blog_article/接受上传文件的页面/index.html" method=post ENCTYPE="multipart/form-data">
<input type="File" name="名字">
</form>
JSP引擎可以让内置对象request调用方法getInputStream()获得一个输入流,通过这个输入流读入客户上传的全部信息,包括文件的内容以及表单域的信息。
根据HTTP协议,文件表单提交的信息中,前4行和后面的5行是表单本身的信息,中间部分才是客户提交的文件的内容。以下说明如何去掉表单的信息:
首
先,我们将客户提交的全部信息保存为一个临时文件,该文件的名字是客户的session对象的ID,不同客户的这个ID是不同的。然后读取该文件的第2
行,这一行中含有客户上传的文件的名字,获取这个名字。再获取第4行结束的位置,以及倒数第6行结束的位置,因为这两个位置之间的内容是上传文件的内容。
然后将这部分内容存入文件,该文件的名字和客户上传的文件名字保持一致。最后删除临时文件。
九、文件下载
JSP
内置对象response调用方法getOutputStream()可以获取一个指向客户的输出流,服务器将文件写入这个流,客户就可以下载这个文件
了。当JSP页面提供下载功能时,应当使用response对象向客户发送HTTP头信息,说明文件的MIME类型,这样,客户的浏览器就会调用相应的外
部程序打开下载的文件。例如,MS
word文件的MIME类型是application/msword,pdf文件的MIME类型是application/pdf。
十、分页读取文件
当读取一个较大的文件时,比如想让客户阅读一部小说,我们希望分页地读取该文件。可以借助session对象实现分页读取文件。当客户向JSP页面发出请求时,JSP页面建立一个指向该文件的输入流,通过输入流每次读取文件的若干行。
HTTP
协议是一种无状态协议。一个客户向服务器发出请求(request),然后服务器返回响应(response),连接就被关闭了。由于在服务器端不保留连
接的有关信息,因此当下一次连接时,服务器已没有以前的连接信息了,无法判断这一次连接和以前的连接是否属于同一客户。也就是说,如果我们请求每次读取
10行,那么第1次请求会读取文件的前10行,当我们第2次请求时,JSP页面会重新将输入流指向文件,这样我们第2次读取的内容和第1次读取的内容完全
相同,仍是文件的前10行。因此,必须使用会话来记录有关连接的信息。当客户选择从文件头开始读取文件时,创建指向文件的输入流连接,然后将这个输入流保
存到客户的会话中。当客户请求读取后10行时,直接使用客户会话中的输入流继续读取文件的后续10行就可以了。为了能够读取JSP文件,我们还需对读出的
文本进行回压流处理。