String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做
在大部分情况下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
在大部分情况下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
Android也为我们提供了SDCard的一些相关操作。Environment这个类就可以实现这个功能。
Environmet类
常用常量
String MEDIA_MOUNTED | 当前Android的外部存储器可读可写 |
String MEDIA_MOUNTED_READ_ONLY | 当前Android的外部存储器只读 |
常用方法
方法名称 | 描述 |
public static File getDataDirectory () | 获得Android下的data文件夹的目录 |
public static File getDownloadCacheDirectory () | 获得Android Download/Cache 内容的目录 |
public static File getExternalStorageDirectory () | 获得Android外部存储器也就是SDCard的目录 |
public static String getExternalStorageState () | 获得Android外部存储器的当前状态 |
public static File getRootDirectory () | 获得Android下的root文件夹的目录 |
要想实现对SDCard的读取操作,只需要按以下几个步骤就行:
1、 先判断这台手机设备上是否有SDCard且具有读写SDCard的权限
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
2、 调用Environment.getExternalStorageDirectory()获得到外部存储器的目录
3、 使用IO流对外部存储器进行文件的读写
4、 别忘记了要在AndroidMainfest.xml中添加权限哦
特别声明:以下操作必须要在如下权限下完成:
-
-
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
-
-
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
实例:读写SDCard上的文件
实现效果
用File Explorer可以看到如下图一样的效果:
开发注意事项:
1、 一定不能忘记添加权限
-
-
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
-
-
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android 文件操作小结:
在android中的文件放在不同位置,它们的读取方式也有一些不同。
一、资源文件的读取:
1) 从resource的raw中读取文件数据:
05 | InputStream in = getResources().openRawResource(R.raw.test); |
08 | int length = in.available(); |
10 | byte [] buffer = new byte [length]; |
16 | res = EncodingUtils.getString(buffer, "BIG5" ); |
2) 从resource的asset中读取文件数据
01 | String fileName = "test.txt" ; |
06 | InputStream in = getResources().getAssets().open(fileName); |
08 | int length = in.available(); |
09 | byte [] buffer = new byte [length]; |
13 | res = EncodingUtils.getString(buffer, "UTF-8" ); |
二、读写/data/data/<应用程序名>目录上的文件:
02 | public void writeFile(String fileName,String writestr{ |
05 | FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE); |
07 | byte [] bytes = writestr.getBytes(); |
20 | public String readFile(String fileName){ |
23 | FileInputStream fin = openFileInput(fileName); |
24 | int length = fin.available(); |
25 | byte [] buffer = new byte [length]; |
27 | res = EncodingUtils.getString(buffer, "UTF-8" ); |
三、读写SD卡中的文件。也就是/mnt/sdcard/目录下面的文件 :
02 | public void writeFileSdcardFile(String fileName,String write_str){ |
05 | FileOutputStream fout = new FileOutputStream(fileName); |
06 | byte [] bytes = write_str.getBytes(); |
19 | public String readFileSdcardFile(String fileName){ |
22 | FileInputStream fin = new FileInputStream(fileName); |
24 | int length = fin.available(); |
26 | byte [] buffer = new byte [length]; |
29 | res = EncodingUtils.getString(buffer, "UTF-8" ); |
四、使用File类进行文件的读写:
02 | public String readSDFile(String fileName) { |
04 | File file = new File(fileName); |
06 | FileInputStream fis = new FileInputStream(file); |
08 | int length = fis.available(); |
10 | byte [] buffer = new byte [length]; |
13 | res = EncodingUtils.getString(buffer, "UTF-8" ); |
20 | public void writeSDFile(String fileName, String write_str){ |
22 | File file = new File(fileName); |
24 | FileOutputStream fos = new FileOutputStream(file); |
26 | byte [] bytes = write_str.getBytes(); |
五、另外,File还有下面一些常用的操作:
01 | String Name = File.getName(); |
02 | String parentPath = File.getParent(); 获得文件或文件夹的父目录 |
03 | String path = File.getAbsoultePath(); |
04 | String path = File.getPath(); |
08 | File[] files = File.listFiles(); |
六、使用RandomAccessFile进行文件的读写:
RandomAccessFile的使用方法比较灵活,功能也比较多,可以使用类似seek的方式可以跳转到文件的任意位置,从文件指示器当前位置开始读写。
它有两种构造方法
new RandomAccessFile(f,"rw");//读写方式
new RandomAccessFile(f,"r");//只读方式
使用事例:
08 | public class RandomAccessFileDemo { |
09 | public static void main(String[] args) throws Exception { |
10 | RandomAccessFile file = new RandomAccessFile( "file" , "rw" ); |
13 | file.writeDouble( 8.236598 ); |
14 | file.writeUTF( "这是一个UTF字符串" ); |
15 | file.writeBoolean( true ); |
17 | file.writeLong(2325451l); |
18 | file.writeUTF( "又是一个UTF字符串" ); |
19 | file.writeFloat( 35 .5f); |
25 | System.out.println( "——————从file文件指定位置读数据——————" ); |
26 | System.out.println(file.readInt()); |
27 | System.out.println(file.readDouble()); |
28 | System.out.println(file.readUTF()); |
31 | System.out.println(file.readLong()); |
33 | file.skipBytes(file.readShort()); |
34 | System.out.println(file.readFloat()); |
37 | System.out.println( "——————文件复制(从file到fileCopy)——————" ); |
39 | RandomAccessFile fileCopy= new RandomAccessFile( "fileCopy" , "rw" ); |
40 | int len=( int )file.length(); |
41 | byte [] b= new byte [len]; |
44 | System.out.println( "复制完成!" ); |
总结:
1、apk中有两种资源文件,使用两种不同的方式进行打开使用。
raw使用InputStream in = getResources().openRawResource(R.raw.test);
asset使用InputStream in = getResources().getAssets().open(fileName);
这些数据只能读取,不能写入。
2、SD卡中的文件使用FileInputStream和FileOutputStream进行文件的操作。
3、存放在数据区(/data/data/..)的文件只能使用openFileOutput和openFileInput进行操作。
注意不能使用FileInputStream和FileOutputStream进行文件的操作。
4、RandomAccess类仅限于文件的操作,不能访问其他IO设备。它可以跳转到文件的任意位置,从当前位置开始读写。
小马的错误:
日后小马如果再在开发过程中碰到有关File类的问题,会继续追加到此文章中,希望对处于跟小马一样阶段的朋友们有所帮忙,谢谢啦,O_O,每天进步一点,加油
本文出自 “酷_莫名简单” 博客,请务必保留此出处http://mzh3344258.blog.51cto.com/1823534/746174
天小马来写下自己的开发过程中碰到的问题和所犯的错,虽然简单,但还是希望通过总结提高自己,哪怕很小的进步,也希望朋友们跟小马多交流,指点小马的不足,多批评小马,有很多东西要学,我们多多交流,共同进步,直接看代码:
- package com.mzh.www;
-
- import java.io.File;
- import java.io.IOException;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Environment;
-
- /**
- * @Title: FileTestActivity.java
- * @Package com.mzh.www
- * @Description: 文件类File的常用方法
- * @author MZH
- * @version V2.2
- */
- public class FileTestActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
-
- //小马写的时候不带后缀名,其实这个要写的
- //而且安卓中不建议用此种写法,支持使用Environment获取路径
- String path = "/sdcard/fileName";
- File file = new File(path); //不多讲
-
-
- //下面是File类的一些静态属性
- //file.separator; 小马以前喜欢用"/",虽然不错,但不支持,接着看下面
-
-
- //举两种 写法:
- //方法一:
- String path2 = Environment.getExternalStorageDirectory()
- .getPath()
- +"/"+"XiaoMa.txt";
- File fileName = new File(path2);
- //此处可以添加对文件的操作,IO流
-
-
- //方法二:
- String path3 = Environment.getExternalStorageDirectory()
- .getPath()
- +File.separator+"XiaoMa.txt";
- File fileNam = new File(path3);
- //此处可以添加对文件的操作,IO流
-
-
- /**
- * 大家是不是发现这两种写法第二种多此一举?其实并非如此的
- *,在Android中,官方鼓励支持使用
- * File.separator来插入"/"符号
- * 因为:不同的机型配置系统等各种因素下,"/"符号的转义字符也会不同*
- *,所以为保险起见,
- * 建议朋友们使用File.separator来区别
- */
-
-
- //下面讲下文件的创建是怎么一回事
- //Android 中创建文件的方式有很多种,小马现在讲下
- //我们经常用到的几种哦,吼吼
- File file3 = new File("path"); //path为要创建文件的路径
- //,相关路径可查看API
-
-
- //创建一个临时文件
- //小马讲下,如果让我们自己创建临时文件时,我们还得拼接文件名
- //,Android为我们提供了更快捷的方式
- //prefix代表:文件名前缀,suffix代表:生成临时文件的格式,
- //如:.txt .amr .jpg .png等等
- try {
- //此处小马未指定路径,它会默认创建在SD卡根目录下
- File tempFile = File.createTempFile("前缀", "格式"); //记得加入try语句块中
-
- //如果想要指定路径,则可以这样写
- File tempFile2 = File.createTempFile("前缀", "格式",new File("指定临时文件路径"));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
-
- //创建文件的方式有三种:要看仔细咯
-
- File file2 = new File(path3); //因为路径是自己指定的,
- //在此小马就直接合上面定义过的路径了
- if(!file2.exists()){
-
- //方式一:
- try {
- file2.createNewFile();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- //方式二:
- //file2.mkdir();
-
- //方式三:
- //file2.mkdirs();
-
- /**
- * 以上创建文件方式好像也没多大不同之处,小马的的错误,
- *创建文件的时候随便调用这三个方法其中之一
- * 但后来发现还是有明显区别的,现在贴一段官方API说明
- *,小马英语也不咋的,希望英语一般的朋友们
- * 看到英语不要怕自己不会翻译什么的,多查单词,
- *不会的再求助工作翻译下,查可以提高自己的英语能力
- */
-
-
-
- /**
- * 小述:讲下“/”与“/”的不同,在创建文件时不能使用使用windows方式,
- *也就是"/",除非你转义有linux方式的话就直接用“/”,省了麻烦,
- *还不会出错转义错误等问题,对吧?
- */
-
-
- /**
- * createNewFile()
- Creates a new, empty file on the file system according to the path information
- stored in this file.
- 这个方法指在指定路径下创建一个empty(空的,小马就认识几个单词,
- *其余的都有道查)文件
- */
-
- /**
- * mkdir()
- Creates the directory named by the trailing filename of
- this file.
- 这个方法指:创建一个指定目录下的文件,但这个方法不能创建多个目录,
- 一般都使用加S的,这个尽量少用,一般私有文件
- 及私有目录的创建用这个方法
- */
-
-
- /**
- * mkdirs()
- Creates the directory named by the trailing filename of this file,
- including the complete directory path required to create this
- directory.
- 这个方法指:创建一个指定目录下的文件,与上面不同的是,
- 此方法可以创建多个目录哦,常用的创建文件的方法
- */
-
- /**
- * 最后,讲下isDirectory() 与 isFile()的小区别
- * 小马刚开始不懂什么是Directory,后来试了下,讲直接的,
- 就是:是否是文件夹,isFile是否是文件,简单吧??O_O
- */
-
-
-
-
-
- }
-
- }
- }
最后,不要忘记加Android中文件操作的权限:
- <!--往sdcard中写入数据的权限 -->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
- <!--在sdcard中创建/删除文件的权限 -->
-
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
- 这些问题都是小马在开发过程中遇到过的问题,虽然很低级 ,
- 但错误犯多了就不会犯了,最后 ,
- 小马希望大家多查英文文档,不管自己
- 英语阅读能力好不好,讲真话,小马的英语,可以让你哭,
- 但要学会善用工具学习,爱编程,就要补编程方面的缺陷,不要被这英语吓到
- 啦,今天就讲这些内容吧,File类中其它方法都很简单,
- 大家可以试着用下词典查下意思,很容易知道它是干吗的方法的,相信小马
- 小马希望:能跟大伙交流学习,共同进步,完成菜鸟中的菜鸟,
- 到高手中的高手的蜕变,高手,是从菜鸟努力导致的,不是生下来就有的,
- 希望我们共同进步