数据写入读取
来源:互联网 发布:阿里巴巴数据库在哪 编辑:程序博客网 时间:2024/05/23 02:05
- <!-- 往SDCard写入数据权限 -->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <!-- 在SDCard中创建与删除文件权限 -->
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
- package com.ppmeet;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import org.apache.http.util.EncodingUtils;
- import android.content.Context;
- /**
- * class name:FileService<BR>
- * class description:android文件的一些读取操作<BR>
- * PS: <BR>
- *
- * @version 1.00 2010/10/21
- * @author CODYY)peijiangping
- */
- public class FileService {
- private Context context;
- public FileService(Context c) {
- this.context = c;
- }
- // 读取sd中的文件
- public String readSDCardFile(String path) throws IOException {
- File file = new File(path);
- FileInputStream fis = new FileInputStream(file);
- String result = streamRead(fis);
- return result;
- }
- // 在res目录下建立一个raw资源文件夹,这里的文件只能读不能写入。。。
- public String readRawFile(int fileId) throws IOException {
- // 取得输入流
- InputStream is = context.getResources().openRawResource(fileId);
- String result = streamRead(is);// 返回一个字符串
- return result;
- }
- private String streamRead(InputStream is) throws IOException {
- int buffersize = is.available();// 取得输入流的字节长度
- byte buffer[] = new byte[buffersize];
- is.read(buffer);// 将数据读入数组
- is.close();// 读取完毕后要关闭流。
- String result = EncodingUtils.getString(buffer, "UTF-8");// 设置取得的数据编码,防止乱码
- return result;
- }
- // 在assets文件夹下的文件,同样是只能读取不能写入
- public String readAssetsFile(String filename) throws IOException {
- // 取得输入流
- InputStream is = context.getResources().getAssets().open(filename);
- String result = streamRead(is);// 返回一个字符串
- return result;
- }
- // 往sd卡中写入文件
- public void writeSDCardFile(String path, byte[] buffer) throws IOException {
- File file = new File(path);
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(buffer);// 写入buffer数组。如果想写入一些简单的字符,可以将String.getBytes()再写入文件;
- fos.close();
- }
- // 将文件写入应用的data/data的files目录下
- public void writeDateFile(String fileName, byte[] buffer) throws Exception {
- byte[] buf = fileName.getBytes("iso8859-1");
- fileName = new String(buf, "utf-8");
- // Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
- // Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
- // Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
- // MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
- // 如果希望文件被其他应用读和写,可以传入:
- // openFileOutput("output.txt", Context.MODE_WORLD_READABLE +
- // Context.MODE_WORLD_WRITEABLE);
- FileOutputStream fos = context.openFileOutput(fileName,
- Context.MODE_APPEND);// 添加在文件后面
- fos.write(buffer);
- fos.close();
- }
- // 读取应用的data/data的files目录下文件数据
- public String readDateFile(String fileName) throws Exception {
- FileInputStream fis = context.openFileInput(fileName);
- String result = streamRead(fis);// 返回一个字符串
- return result;
- }
- }
一、序言
IO操作,才程序中比较普遍,JAVA 中提出了IO/NIO 的概念,也一直在说NIO 比IO快,一直不知道原因,就想memcache 和ehcache 比较优劣一样,这些东西得自己看看如何实现的,才 知道区别,从而才知道优劣以及试用范围,而不仅仅是“听说”!这里我可以先了解下JAVA 如何操作IO的。
二、代码示例
我们先看看简单文件操作:
- // 这是将文件转换成输入流的的一种方式,获得了流我们就能干很多事
- FileInputStream in = new FileInputStream(new File("...file"));
再看看FileInputStream 的源码:
- public FileInputStream(File file) throws FileNotFoundException {
- String name = (file != null ? file.getPath() : null);
- // 安全管理器,这里暂时不说
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- // 检查是否可以按这名字读取
- security.checkRead(name);
- }
- if (name == null) {
- throw new NullPointerException();
- }
- // 获得文件描述,这个JDK 未公布
- fd = new FileDescriptor();
- // 打开文件,这是个native 方法,我们可以用openjdk 看看里面
- open(name);
- }
在FileInputStream.c下可以找到方法
- // open 方法
- JNIEXPORT void JNICALL
- Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
- fileOpen(env, this, path, fis_fd, O_RDONLY);
- }
OK。我们从该文件上面的引用io_util_md.c找到实现:
- void
- fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
- {
- jlong h = winFileHandleOpen(env, path, flags);
- if (h >= 0) {
- // 设置fd 的值
- SET_FD(this, h, fid);
- }
- }
在上面文件里面可以看到:winFileHandleOpen,
- jlong
- winFileHandleOpen(JNIEnv *env, jstring path, int flags)
- {
- const DWORD access =
- (flags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
- (flags & O_WRONLY) ? GENERIC_WRITE :
- GENERIC_READ;
- const DWORD sharing =
- FILE_SHARE_READ | FILE_SHARE_WRITE;
- const DWORD disposition =
- /* Note: O_TRUNC overrides O_CREAT */
- (flags & O_TRUNC) ? CREATE_ALWAYS :
- (flags & O_CREAT) ? OPEN_ALWAYS :
- OPEN_EXISTING;
- const DWORD maybeWriteThrough =
- (flags & (O_SYNC | O_DSYNC)) ?
- FILE_FLAG_WRITE_THROUGH :
- FILE_ATTRIBUTE_NORMAL;
- const DWORD maybeDeleteOnClose =
- (flags & O_TEMPORARY) ?
- FILE_FLAG_DELETE_ON_CLOSE :
- FILE_ATTRIBUTE_NORMAL;
- const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;
- HANDLE h = NULL;
- if (onNT) {
- WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE);
- if (pathbuf == NULL) {
- /* Exception already pending */
- return -1;
- }
- h = CreateFileW(
- pathbuf, /* Wide char path name */
- access, /* Read and/or write permission */
- sharing, /* File sharing flags */
- NULL, /* Security attributes */
- disposition, /* creation disposition */
- flagsAndAttributes, /* flags and attributes */
- NULL);
- free(pathbuf);
- } else {
- WITH_PLATFORM_STRING(env, path, _ps) {
- h = CreateFile(_ps, access, sharing, NULL, disposition,
- flagsAndAttributes, NULL);
- } END_PLATFORM_STRING(env, _ps);
- }
- if (h == INVALID_HANDLE_VALUE) {
- int error = GetLastError();
- if (error == ERROR_TOO_MANY_OPEN_FILES) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "IOException",
- "Too many open files");
- return -1;
- }
- throwFileNotFoundException(env, path);
- return -1;
- }
- return (jlong) h;
- }
好吧,上面代码我也搞不明白- -,但是这几句代码:
- h = CreateFileW(
- pathbuf, /* Wide char path name */
- access, /* Read and/or write permission */
- sharing, /* File sharing flags */
- NULL, /* Security attributes */
- disposition, /* creation disposition */
- flagsAndAttributes, /* flags and attributes */
- NULL);
- 以及
- WITH_PLATFORM_STRING(env, path, _ps) {
- h = CreateFile(_ps, access, sharing, NULL, disposition,
- flagsAndAttributes, NULL);
我的理解是,这里通过CreateFileW方法,创建了一个类似文件描述的结构,然后通过CreateFile调windows 下面的底层方法,填充这个结构的数据,那么这个文件对象就能被我们上层对象识别了,就能是获取里面的资源。
OK,我们现在创建了对文件之间的连接,拿到文件流对象之后,来看看我们常用的read 方法。
- // 对字节的操作
- public native int read() throws IOException;
- private native int readBytes(byte b[], int off, int len) throws IOException;
在FileInputStream.c 里面同样可以找到
- JNIEXPORT jint JNICALL
- Java_java_io_FileInputStream_read(JNIEnv *env, jobject this) {
- return readSingle(env, this, fis_fd);
- }
- JNIEXPORT jint JNICALL
- Java_java_io_FileInputStream_readBytes(JNIEnv *env, jobject this,
- jbyteArray bytes, jint off, jint len) {
- return readBytes(env, this, bytes, off, len, fis_fd);
- }
继续看io_util.c 里面:
- jint
- readSingle(JNIEnv *env, jobject this, jfieldID fid) {
- jint nread;
- char ret;
- FD fd = GET_FD(this, fid);
- if (fd == -1) {
- JNU_ThrowIOException(env, "Stream Closed");
- return -1;
- }
- // 看出是一个一个的读取,fd 表示刚才文件描述的一种结构
- nread = IO_Read(fd, &ret, 1);
- if (nread == 0) { /* EOF */
- return -1;
- } else if (nread == JVM_IO_ERR) { /* error */
- JNU_ThrowIOExceptionWithLastError(env, "Read error");
- } else if (nread == JVM_IO_INTR) {
- JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
- }
- return ret & 0xFF;
- }
关于IO_Read 的东西,在io_util_md.h 有定义:
- /*
- * HPI是一个与主机通信的并行接口
- * Route the routines through HPI
- */
- #define IO_Write JVM_Write
- #define IO_Sync JVM_Sync
- <strong>#define IO_Read JVM_Read</strong>
- #define IO_Lseek JVM_Lseek
- #define IO_Available JVM_Available
- #define IO_SetLength JVM_SetLength
关于JVM_Read 我在jvm.h 里面看到
- /*
- // 从文件里面读取 a char array
- * Read data from a file decriptor into a char array.
- * // 文件的来源
- * fd the file descriptor to read from.
- // 读出来的存放位置
- * buf the buffer where to put the read data.
- // 读的字节数
- * nbytes the number of bytes to read.
- *
- * This function returns -1 on error, and 0 on success.
- */
- JNIEXPORT jint JNICALL
- JVM_Read(jint fd, char *buf, jint nbytes);
然后在jvm.cpp 里面找到
关于这段代码,大神告诉我是宏定义,关于C和C++ 的东西,我已经无力回天啦。
当然我们知道了介绍,可以理解这里会让调系统的read 方法。
这可以参考:“操作系统read 的原理实现”,google 一下很多,这里就不解释了
jvm.cpp 里面有很多关于IO这块的,可以去看看,但是都是 宏定义。。
关于linux 下的这些代码,还有涉及一下阻塞等东西,以后在去研究一下操作系统的东西吧。
- JVM_LEAF(jint, JVM_Read(jint fd, char *buf, jint nbytes))
- JVMWrapper2("JVM_Read (0x%x)", fd);
- //%note jvm_r6
- return (jint)os::restartable_read(fd, buf, nbytes);
- JVM_END
- 读取写入SharedPreferences数据
- 数据写入读取
- Excel 数据的读取写入
- json读取和写入数据
- poi读取数据写入excel
- R数据读取和写入
- 磁盘扇区数据的读取和写入
- Java使用URLConnection写入和读取数据
- 关于XML的读取与写入数据
- java一行一行写入或读取数据
- 打开 txt 读取数据 写入实例
- PHP大数据文本读取与写入
- java一行一行写入或读取数据
- excel在android读取,写入,更新数据
- C# xml文件读取节点写入数据
- .Net读取Excle数据写入到数据库
- 数据的读取与写入体验
- 完善数据的读取与写入体验!
- Tip: char *和char*的区别
- Netty4学习笔记(一) 基础篇
- binder通信
- solutino Of Pat 1112. Stucked Keyboard (20)
- Swift基础1.2——基本语法—Optional 可选项
- 数据写入读取
- Nginx详解-服务器集群()
- Swift基础1.3——基本语法——控制流
- Error:Unable to start the daemon process: could not reserve enough space for object heap.
- Swift基础1.4——基本语法——字符串
- 蒙特卡罗树搜索+深度学习 -- AlphaGo原版论文阅读笔记
- Netty4学习笔记(二) TCP黏包/拆包解决办法
- Swift基础1.5——基本语法——集合
- 数据结构之——单链表的实现