文件 IO
读和写
流就是管道,向管道里面写数据用输出流:write
从管道里面读数据,用输入流:read
流的分类
流,按照不同的维度有不同的分类,按照从流中每次读取数据单位不同,划分为字节流字符流。
按照流-对应操作的角色的不同(是 IO 设备,还是其他流)是否能够直接向特定的 IO 设备如文件、网络、磁盘等,能够直接与这些进行读写的称之为节点流,
对节点流进一步封装的流,通过封装后的流来实现读写功能,处理流也被称为高级流。
注意事项
1、流和数组不一样,不能通过索引读写数据。在流中,你也不能像数组那样前后移动读取数据,除非使用 RandomAccessFile 处理文件。
2、流仅仅只是一个连续的数据流。流中的数据只能够顺序访问。当达到流末尾时,返回-1。
3、InputStream 的 read()方法返回一个字节大小,返回值的范围在 0 到 255 之间。
4、Reader 的 read()方法返回一个字符,会根据文本的编码,一次读取一个或者多个字节,返回值的范围在 0 到 65535 之间。
5、read(byte[])会尝试读取与给定字节数组容量一样大的字节数,返回值 int 表示已经读取过的字节数。如果 InputStream 内可读的数据不足以填满字节数组,那么数组剩余的部分将包含本次读取之前的数据。记得检查有多少数据实际被写入到了字节数组中。
6、read(byte, int offset, int length)同样将数据读取到字节数组中,不同的是,该方法从数组的 offset 位置开始,并且最多将 length 个字节写入到数组中。同样地,read(byte, int offset, int length)方法返回一个 int 变量,表示有多少字节已经被写入到字节数组中,所以请记得在读取数据前检查上一次调用 read(byte, int offset, int length)的返回值。
读取文本文件内容
/*** 读取文本文件内容 * @param filePathAndName* 带有完整绝对路径的文件名* @param encoding* 文本文件打开的编码方式* @return 返回文本文件的内容*/public static String readTxt(String filePathAndName, String encoding) {encoding = encoding.trim();StringBuilder str = new StringBuilder("");String st = "";FileInputStream fs = null;InputStreamReader isr=null;try {fs = new FileInputStream(filePathAndName); if (encoding.equals("")) { isr = new InputStreamReader(fs); } else { isr = new InputStreamReader(fs, encoding); } BufferedReader br = new BufferedReader(isr); try { String data = ""; while ((data = br.readLine()) != null) { str.append(data + " "); } } catch (Exception e) { str.append(e.toString()); } finally { br.close(); } st = str.toString(); } catch (IOException es) { st = ""; } finally { if (null != fs) { try { fs.close(); } catch (IOException e) { message = "读取文本出错"; } } if(null!=isr){ try { isr.close(); } catch (IOException e) { message = "读取文本出错"; } } } return st;}读取文件内容
/** * 读取文本文件内容 * * @param filePathAndName * 带有完整绝对路径的文件名 * @param encoding * 文本文件打开的编码方式 * @return 返回文本文件的每一行内容 */ public static List<String> readLineTxt(String filePathAndName, String encoding) { encoding = encoding.trim(); List<String> st = new ArrayList<String>(); FileInputStream fs = null; InputStreamReader isr = null; try { fs = new FileInputStream(filePathAndName);
if (encoding.equals("")) { isr = new InputStreamReader(fs); } else { isr = new InputStreamReader(fs, encoding); } BufferedReader br = new BufferedReader(isr); try { String data = ""; while ((data = br.readLine()) != null) { st.add(data); } } catch (Exception e) { message = "读取文本出错"; } finally { br.close(); } } catch (IOException es) { st.clear(); } finally { if (null != fs) { try { fs.close(); } catch (IOException e) { message = "读取文本出错"; } } if (null != isr) { try { isr.close(); } catch (IOException e) { message = "读取文本出错"; } } } return st; }
新建目录
/** * 新建目录 * * @param folderPath * 目录 * @return 返回目录创建后的路径 */ public static String createFolder(String folderPath) { String txt = folderPath; try { File myFilePath = new File(txt); txt = folderPath; if (!myFilePath.exists()) { myFilePath.mkdir(); } } catch (Exception e) { message = "创建目录操作出错"; } return txt; }多级目录创建
/** * 多级目录创建 * * @param folderPath * 准备要在本级目录下创建新目录的目录路径 例如 c:myf * @param paths * 无限级目录参数,各级目录以单数线区分 例如 a|b|c * @return 返回创建文件后的路径 例如 c:myfac */public static String createFolders(String folderPath, String paths) { String txts = folderPath; try { String txt; txts = folderPath; StringTokenizer st = new StringTokenizer(paths, "|"); for (; st.hasMoreTokens();) { txt = st.nextToken().trim(); if (txts.lastIndexOf("/") != -1) { txts = createFolder(txts + txt); } else { txts = createFolder(txts + txt + "/"); } } } catch (Exception e) { message = "创建目录操作出错!"; } return txts;}新建文件
/** * 新建文件 * * @param filePathAndName * 文本文件完整绝对路径及文件名 * @param fileContent * 文本文件内容 * @return */ public static void createFile(String filePathAndName, String fileContent) { try { String filePath = filePathAndName; filePath = filePath.toString(); File myFilePath = new File(filePath); if (!myFilePath.exists()) { if (!myFilePath.createNewFile()) { return; } } FileWriter resultFile = null; try { resultFile = new FileWriter(myFilePath); } catch (Exception e) { message = "创建文件操作出错"; } finally { if (null != resultFile) { resultFile.close(); } }
PrintWriter myFile = null; try { myFile = new PrintWriter(resultFile); String strContent = fileContent; myFile.println(strContent); } catch (Exception e) { message = "创建文件操作出错"; } finally { if (null != myFile) { myFile.close(); } } } catch (Exception e) { message = "创建文件操作出错"; } }
有编码方式的文件创建
/** * 有编码方式的文件创建 * * @param filePathAndName * 文本文件完整绝对路径及文件名 * @param fileContent * 文本文件内容 * @param encoding * 编码方式 例如 GBK 或者 UTF-8 * @return */ public static void createFile(String filePathAndName, String fileContent, String encoding) {
try { String filePath = filePathAndName; filePath = filePath.toString(); logger.info("start create file,fileName:{}",filePathAndName); File myFilePath = new File(filePath); if (!myFilePath.exists()) { File parentFile= myFilePath.getParentFile(); if(!parentFile.exists()){ logger.info("there's no file parent dir,create direction:{}",parentFile); parentFile.mkdirs(); } if (!myFilePath.createNewFile()) { return; } } PrintWriter myFile = null; try { myFile = new PrintWriter(myFilePath, encoding); String strContent = fileContent; myFile.println(strContent); logger.info(" end write file,fileName:{}",filePathAndName); } catch (Exception e) { message = "创建文件操作出错"; } finally { if (null != myFile) { myFile.close(); } }
} catch (Exception e) { message = "创建文件操作出错"; } }删除文件
/** * 删除文件 * * @param filePathAndName * 文本文件完整绝对路径及文件名 * @return Boolean 成功删除返回true遭遇异常返回false */ public static boolean delFile(String filePathAndName) { boolean bea = false; try { String filePath = filePathAndName; File myDelFile = new File(filePath); if (myDelFile.exists()) { if (!myDelFile.delete()) { return false; } bea = true; } else { bea = true; } } catch (Exception e) { message = (filePathAndName + "删除文件操作出错 " + e.toString()); } return bea; }删除文件夹
删除文件夹/** * 删除文件夹 * * @param folderPath * 文件夹完整绝对路径 * @return */ public static void delFolder(String folderPath) { try { delAllFile(folderPath); // 删除完里面所有内容 String filePath = folderPath; filePath = filePath.toString(); File myFilePath = new File(filePath); // 删除空文件夹 if (!myFilePath.delete()) { return; } } catch (Exception e) { message = ("删除文件夹操作出错"); } }
删除文件夹下所有文件
/** * 删除指定文件夹下所有文件 * * @param path * 文件夹完整绝对路径 * @return * @return */public static boolean delAllFile(String path) { boolean bea = false; File file = new File(path); if (!file.exists()) { return bea; } if (!file.isDirectory()) { return bea; } String[] tempList = file.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if (path.endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { if (!temp.delete()) { return false; } } if (temp.isDirectory()) { delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件 delFolder(path + "/" + tempList[i]);// 再删除空文件夹 bea = true; } } return bea;}复制单个文件
/** * 复制单个文件 * * @param oldPathFile * 准备复制的文件源 * @param newPathFile * 拷贝到新绝对路径带文件名 * @return */ public static void copyFile(String oldPathFile, String newPathFile) { InputStream inStream = null; FileOutputStream fs = null;
try { int bytesum = 0; int byteread = 0; File oldfile = new File(oldPathFile); if (oldfile.exists()) { // 文件存在时 inStream = new FileInputStream(oldPathFile); // 读入原文件 fs = new FileOutputStream(newPathFile); byte[] buffer = new byte[1024]; while ((byteread = inStream.read(buffer)) != -1) { bytesum += byteread; // 字节数 文件大小 System.out.println(bytesum); fs.write(buffer, 0, byteread); } inStream.close(); fs.close(); } } catch (Exception e) { message = ("复制单个文件操作出错"); } finally { try { if (null != inStream) { inStream.close(); } } catch (IOException e) { message = ("复制单个文件操作出错"); } try { if (null != fs) { fs.close(); } } catch (IOException e) { message = ("复制单个文件操作出错"); } } }
复制整个文件夹内容
/** * 复制整个文件夹的内容 * * @param oldPath * 准备拷贝的目录 * @param newPath * 指定绝对路径的新目录 * @return */ public static void copyFolder(String oldPath, String newPath) { try { new File(newPath).mkdirs(); // 如果文件夹不存在 则建立新文件夹 File a = new File(oldPath); String[] file = a.list(); File temp = null; for (int i = 0; i < file.length; i++) { if (oldPath.endsWith(File.separator)) { temp = new File(oldPath + file[i]); } else { temp = new File(oldPath + File.separator + file[i]); } if (temp.isFile()) { FileInputStream input = null; FileOutputStream output = null; try { input = new FileInputStream(temp); output = new FileOutputStream(newPath + "/" + (temp.getName()).toString()); byte[] b = new byte[1024 * 5]; int len; while ((len = input.read(b)) != -1) { output.write(b, 0, len); } output.flush(); } catch (Exception e) { message = "复制整个文件夹内容操作出错"; } finally { if (null != output) { output.close(); } if (null != input) { input.close(); } } } if (temp.isDirectory()) {// 如果是子文件夹 copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]); } } } catch (Exception e) { message = "复制整个文件夹内容操作出错"; } }移动文件
/** * 移动文件 * * @param oldPath * @param newPath * @return */public static void moveFile(String oldPath, String newPath) { copyFile(oldPath, newPath); delFile(oldPath);}
移动文件到目录
/** * 移动文件到目录 * * @param filePath * @param destDirectory * @return */public static void moveFileToDirectory(String filePath, String destDirectory) { File file = new File(filePath); try { if (file.exists()) { FileUtils.copyFileToDirectory(file, new File(destDirectory)); FileUtils.deleteQuietly(file); } } catch (IOException e) { message = "Failed to move files to the directory, ".concat(e.getMessage()); }}拷贝文件到目录
/** * 拷贝文件到目录 * * @param filePath * @param destDirectory * @return */public static void copyFileToDirectory(String filePath, String destDirectory) { File file = new File(filePath); try { if (file.exists()) { FileUtils.copyFileToDirectory(file, new File(destDirectory)); } } catch (IOException e) { message = "Failed to copy files to the directory, ".concat(e.getMessage()); }}移动目录
/** * 移动目录 * * @param oldPath * @param newPath * @return */public static void moveFolder(String oldPath, String newPath) { copyFolder(oldPath, newPath); delFolder(oldPath);}移动目录下所有文件到另外一个目录
/** * 移动目录下所有文件到另外一个目录 * * @param oldPath * @param newPath * @return */public static boolean moveFolderFile(String oldPath, String newPath) { try { new File(newPath).mkdirs(); // 如果文件夹不存在 则建立新文件夹 File a = new File(oldPath); File[] files = a.listFiles(); if (newPath.lastIndexOf("/") == -1) { newPath = newPath + "/"; } for (int i = 0; i < files.length; i++) { String fileName = files[i].getName(); if (!files[i].renameTo(new File(newPath + fileName))) { return false; } } } catch (Exception e) { message = "剪切整个文件夹内容操作出错" + e.getMessage(); return false; } return true;}得到错误信息
/** * 得到错误信息 */public static String getMessage() { return message;}
按批次读取文件,一般适用于大文件
/** * 按批次读取文件,一般适用于大文件 * * @param start * 开始位置,指的是offset而非行号 * @param maxBatch * 一批次读取的最大行数 * @param file * 文件对象 * @return 文件批次对象 * @throws IOException */public static FileParseBean readFileByBatch(int start, int maxBatch, File file) { FileParseBean batchReadFile = new FileParseBean(); InputStreamReader isr = null; BufferedReader br = null; try { String line = ""; isr = new InputStreamReader(new FileInputStream(file), Const.UTF8); br = new BufferedReader(isr, BUFFER_SIZE); List<String> batchDataList = new ArrayList<String>(); int lineNumber = 1; br.skip(start); while ((line = br.readLine()) != null) { batchDataList.add(line); start = start + line.length() + 2; if (lineNumber == maxBatch) { break; } lineNumber++; } batchReadFile.setBatchDataList(batchDataList); batchReadFile.setOffset(start); if ((line = br.readLine()) == null) { batchReadFile.setFinished(true); } else { batchReadFile.setFinished(false); } } catch (IOException e) { message = "Failed to read file by batch, ".concat(e.getMessage()); } finally { try { if (br != null) { br.close(); } if (isr != null) { isr.close(); } } catch (IOException e) { message = "Failed to close file read stream, ".concat(e.getMessage()); } } return batchReadFile;}按行号读取一行的内容
/** * 按行号读取一行的内容 * * @param lineNumber * 行号,从1开始计算 * 文件路径 * @return 行内容 * @throws IOException */public static String readLineByNumber(int lineNumber, File file) { String line = ""; BufferedReader br = null; try { br = new BufferedReader(new FileReader(file), BUFFER_SIZE); int currentLineNumber = 1; while ((line = br.readLine()) != null) { if (currentLineNumber == lineNumber) { break; } currentLineNumber++; } } catch (IOException e) { message = "Failed to read file by line number, ".concat(e.getMessage()); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { message = "Failed to close file read stream, ".concat(e.getMessage()); } } return line;}按列表写入文件
/** * 按列表写入文件,数据列表的一行对应文件的一行 * * @param dataList * 数据列表 * 文件路径 * @return 写入结果 * @throws Exception */public static boolean writeFile(List<String> dataList, File file) { return writeFile(dataList, file, "\r\n");}
/** * 按列表写入文件,数据列表的一行对应文件的一行 * * @param dataList * 数据列表 * 文件路径 * @param lineSplit * 行分隔符 * @return 写入结果 * @throws Exception */ public static boolean writeFile(List<String> dataList, File file, String lineSplit) { boolean success = true; OutputStream os = null; OutputStreamWriter writer = null; BufferedWriter bw = null; try { os = new FileOutputStream(file); writer = new OutputStreamWriter(os); bw = new BufferedWriter(writer); for (String line : dataList) { bw.write(line.concat(lineSplit)); } bw.flush(); } catch (Exception e) { success = false; message = "Failed to write file, ".concat(e.getMessage()); } finally { try { if (bw != null) { bw.close(); } if (writer != null) { writer.close(); } if (os != null) { os.close(); } } catch (IOException e) { message = "Failed to close file write stream, ".concat(e.getMessage()); } } return success; }
向文件末尾写入字符串数据
/** * 向文件末尾写入字符串数据 * * @param data * 数据 * @param file * 文件对象 * @param append * 追加还是覆盖模式 true-追加 ,false-覆盖 * @return 写入结果 * @throws IOException */ public static boolean writeFile(String data, File file, boolean append) {
boolean success = true; OutputStream os = null; OutputStreamWriter writer = null; BufferedWriter bw = null; try { os = new FileOutputStream(file, append); writer = new OutputStreamWriter(os); bw = new BufferedWriter(writer); bw.write(data); bw.flush(); } catch (Exception e) { success = false; message = "Failed to write file, ".concat(e.getMessage()); } finally { try { if (bw != null) { bw.close(); } if (writer != null) { writer.close(); } if (os != null) { os.close(); } } catch (IOException e) { message = "Failed to close file write stream, ".concat(e.getMessage()); } } return success; }通过过目录和文件名拼接绝对路径
/** * 通过目录和文件名称拼接文件绝对路径 * @param path 目录 * @param fileName 文件名 * @return 文件的绝对路径 */public static String getFilePath(String path, String fileName) { StringBuilder sb = new StringBuilder(); path = path.replaceAll("\\\\", "/"); if (path.lastIndexOf("/") == -1) { sb.append(path).append("/").append(fileName); } else { sb.append(path).append(fileName); } return sb.toString();}生成文件
public static boolean createCBFile(String fileName, ArrayList<String[]> data, String createFilePath, String split, String userId, String userName) throws IOException, ExecutionException, JSchException {
isChartPathExist(createFilePath); if(data.size()<=0){ insertOperateLog("生成文件", "", "fail", userId, userName, "账单数据错误"); logger.warn("file {} to upload is empty.", fileName); return false; } String content = convertData2Content(data,split);
File localFile = new File(createFilePath+fileName); FileWriter writer = null; try { if (localFile.exists()) { writer = new FileWriter(localFile, true); writer.write(content); } else { writer = new FileWriter(localFile, false); writer.write(content); } } catch (Exception e) { boolean insert = insertOperateLog("生成文件", "", "fail", userId, userName, "异常"); if (!insert) { logger.info("日志插入失败"); } logger.error(e.getMessage()); return false; } finally { if (null != writer) { writer.close(); } }
return true; }
下载文件
public HttpServletResponse downloadCBFile(@RequestParam String cycleId, HttpServletResponse response) { Map resultContext = fileList.getResultContext(); ArrayList fileName =(ArrayList) resultContext.get("fileName");
for (Object name : fileName) { String s = name.toString(); byte[] byt = (byte[]) resultContext.get(s);
InputStream input = new ByteArrayInputStream(byt); OutputStream outputStream = null; try { //设置Http响应头 response.setHeader("Content-Disposition", "attachment;Filename=" + URLEncoder.encode(s, "UTF-8")); response.setContentType("application/octet-stream; charset=UTF-8");
outputStream = response.getOutputStream(); byte[] bytes = new byte[2048]; int len; while ((len = input.read(bytes)) > 0) { outputStream.write(bytes, 0, len); } } catch (Exception e) { logger.info("系统异常" + e.getMessage()); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e1) { status = "2"; dealResult = "fail"; failReason = "IO异常"; logger.info("系统IO异常" + e1.getMessage()); } } if (input != null) { try { input.close(); } catch (IOException e1) { status = "3"; dealResult = "fail"; failReason = "IO异常"; logger.info("系统IO异常" + e1.getMessage()); } } } } return response;}版权声明: 本文为 InfoQ 作者【拾贝】的原创文章。
原文链接:【http://xie.infoq.cn/article/90f3feeb387b0d5a35b21149c】。文章转载请联系作者。
拾贝
还未添加个人签名 2019.05.10 加入
还未添加个人简介











评论