本文目錄一覽:
Java的概念和定義是什麼?
Java是一門面向對象編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特徵。Java語言作為靜態面向對象編程語言的代表,極好地實現了面向對象理論,允許程序員以優雅的思維方式進行複雜的編程 。
java中,文件輸入操作由下面哪個
Java 操作文件包括了兩個層面:
在文件系統的層面上來操作文件,包括創建文件、刪除文件、創建目錄、拷貝文件等等。
操作文件里保存的數據,包括讀文件、寫文件。
1. 在文件系統層面操作文件
1.1 File 類介紹
Java 中通過 java.io.File 類來對一個文件(包括目錄)進行抽象的描述。不過有 File 對象,並不代表對應的文件真實存在。
1.2 File 常見屬性
屬性 修飾符及類型 說明
pathSeparator static String 依賴於系統的路徑分隔符,String 類型的表示
pathSeparator static char 依賴於系統的路徑分隔符,char 類型的表示
1.3 File 構造方法
構造方法 說明
File(File parent, String child) 根據父目錄+孩子文件路徑,創建一個新的 File 實例
File(String pathname) 根據文件路徑創建一個新的 File 實例,路徑可以是絕對路徑或者相對路徑
File(String parent, String child) 根據父目錄路徑+孩子文件路徑,創建一個新的 File 實例
1.4 File 常用方法
方法 返回值類型 說明 注意
getParent() String 返回 File 對象的父目錄文件路徑
getName() String 返回 File 對象的純文件名稱
getPath() String 返回 File 對象的文件路徑
getAbsolutePath() String 返回 File 對象的絕對路徑
getCanonicalPath() String 返回 File 對象的修飾過的絕對路徑 如果絕對路徑的值為:d:/././test.txt,那麼修飾過的絕對路徑就為:d:/test.txt。
exists() boolean 判斷 File 對象描述的文件是否真實存在
isDirectory() boolean 判斷 File 對象代表的文件是否是一個目錄
isFile() boolean 判斷 File 對象代表的文件是否是一個普通文件
createNewFile() boolean 根據 File 對象,自動創建一個空文件。成功創建後返回 true 如果文件路徑不正確或者沒有許可權,則可能創建失敗。
delete() boolean 根據 File 對象,刪除該文件。成功刪除後返回 true 如果文件路徑不正確或者沒有許可權,則可能刪除失敗。
deleteOnExit() void 根據 File 對象,標註文件將被刪除,刪除動作會到 JVM 運行結束時才會進行
list() String[] 返回 File 對象代表的目錄下的所有文件名
listFiles() File[] 返回 File 對象代表的目錄下的所有文件,以 File 對象表示
mkdir() boolean 創建 File 對象代表的目錄
mkdirs() boolean 創建 File 對象代表的目錄,如果必要,會創建中間目錄
renameTo(File dext) boolean 重命名文件或移動文件,當目錄為空時也可以重命名目錄
canRead() boolean 判斷用戶是否對文件有可讀許可權
canWrite() boolean 判斷用戶是否對文件有可寫許可權
2. 操作文件里的數據
文件內容的操作包括讀文件和寫文件,而對於這兩種操作 Java 又提供了兩種不同的類:
讀類 寫類 說明
InputStream OutputStream 位元組流,針對二進位文件進行讀寫,操作基本單位是位元組
Reader Writer 字元流,針對文本文件進行讀寫,操作基本單位是字元
位元組流: 它處理單元為1個位元組,操作位元組和位元組數組,存儲的是二進位文件,如果是音頻文件、圖片、歌曲,就用位元組流。
字元流: 它處理的單元為2個位元組的 Unicode 字元,分別操作字元、字元數組或字元串,字元流是由 Java 虛擬機將位元組轉化為2個位元組的 Unicode 字元為單位的字元而成的,如果是關係到中文(文本)的,用字元流更好。
所有文件都是以位元組的形式儲存,在磁碟上保留的並不是文件的字元而是先把字元編碼成位元組,再儲存這些位元組到磁碟。在讀取文件(特別是文本文件)時,也是一個位元組一個位元組地讀取以形成位元組序列。
位元組流可用於任何類型的對象,包括二進位對象,而字元流只能處理字元或者字元串。
位元組流提供了處理任何類型的 IO 操作的功能,但它不能直接處理 Unicode 字元,而字元流就可以。
位元組流在操作的時候本身不會用到緩衝區的,是與文件本身直接操作的;而字元流在操作的時候會使用到緩衝區的。
其中 InputStream/OutputStream 和 Reader/Writer 都實現了 Closeable 介面,所以可以不主動通過 close 方法去關閉該資源,而是通過代碼可讀性更高的 try-with-resource 操作在 try 中的內容結束後,無論是否有異常都關閉該資源。
使用 OutputStream 或 writer 打開文件默認會清空之前的文件內容
2.1 操作位元組流數據
2.1.1 InputStream
InputStream 是一個抽象類,使用時需要使用具體的實現類。InputStream 的實現類很多,針對不同的輸入設備都可以對應一個實現類,其中針對文件讀取的實現類是 FileInputStream。
FileInputStream 構造方法:
構造方法 說明
FileInputStream(File file) 利用 File 構造對應文件輸入流
FileInputStream(String name) 利用文件路徑構造對應文件輸入流
InputStream 核心方法:
方法 返回值類型 說明
read() int 一次讀取一個位元組的數據,如果返回 -1 表示文件讀完了
read(byte[] b) int 一次最多讀取 b.length 位元組的數據到 b 中,返回值為實際讀到的位元組數量,如果返回 -1 表示文件讀完了
read(byte[] b, int off, int len) int 一次最多讀取 len 個位元組到 b 中,並從 off 的位置開始存放,返回值為實際讀到的位元組數量,如果返回 -1 表示文件讀完了
close() void 關閉位元組流
為什麼 read 方法的返回值是 Int 類型?
對於 read 方法的返回值,當讀取的是數字和英文時,返回值是對應的 ascii 碼;當讀取的是漢字時,返回的是漢字的機內碼,比如使用的是 GBK 編碼方式,返回的就是 GBK 的內部編碼。read 方法每次從 inputstream 中讀取一個位元組,而一個位元組是8位,但當最高位是1的時候,二進位對應的 ascii 碼值就是複數,而 ascii 是沒有負數的,所以用 byte 類型表示不了。並且 11111111 對應的十進位值是 -1,而返回 -1 表示文件讀取完畢了,則後面的數據就不會讀了,因此 byte 類型不適合,int 類型則可以解決這個問題。
示例代碼: 使用 read() 方法讀取文件內容
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File(“./test.txt”);
StringBuilder sb = new StringBuilder();
try (InputStream inputStream = new FileInputStream(file)){
while(true) {
int b = inputStream.read();
if(b == -1){
break;
}
sb.append((char) b);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(sb.toString());
}
}
登錄後複製

示例代碼: 使用 read(byte[] b) 方法讀取文件內容
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File(“./test.txt”);
byte[] buffer = new byte[1024];
try (InputStream inputStream = new FileInputStream(file)){
while(true) {
int len = inputStream.read(buffer);
if(len == -1){
break;
}
String s = new String(buffer, 0, len, “utf-8”);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
登錄後複製

2.1.2 OutputStream
OutputStream 是一個抽象類,使用時需要使用具體的實現類。OutputStream 的實現類很多,針對不同的輸出設備都可以對應一個實現類,其中針對文件讀取的實現類是 FileOutputStream。
FileOutputStream 構造方法:
構造方法 說明
FileOutputStream(File file) 利用 File 構造對應文件輸出流
FileOutputStream(String name) 利用文件路徑構造對應文件輸出流
FileOutputStream(File file, boolean append) append 表示是否追加數據到文件的末尾,為 true 表示追加,為 false 表示情空之前的內容重新加入
FileOutputStream(String name, boolean append) append 表示是否追加數據到文件的末尾,為 true 表示追加,為 false 表示情空之前的內容重新加入
OutputStream 核心方法:
方法 返回值類型 說明
write() int 一次寫入一個位元組的數據
write(byte[] b) int 一次最多寫入 b.length 位元組的數據到 b 中,返回值為實際寫入的位元組數量
write(byte[] b, int off, int len) int 一次最多寫入 len 個位元組到 b 中,並從 off 的位置開始存放,返回值為實際寫入到的位元組數量
close() void 關閉位元組流
示例代碼:
public class Demo1{
public static void main(String[] args) throws IOException {
File in = new File(“./in.txt”);
File out = new File(“./out.txt”);
byte[] buffer = new byte[1024];
try (InputStream inputStream = new FileInputStream(in);
OutputStream outputStream = new FileOutputStream(out)) {
while (true) {
int len = inputStream.read(buffer);
if (len == -1) {
break;
}
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
登錄後複製

2.1.3 BufferedInputStream
BufferedInputStream 也是 InputStream 的具體實現類,相比於 FileInputStream 優化了系統調用,即通俗解釋為:將數據保存了緩存區,但是減少磁碟 IO 並不是 BufferedInputStream 來做的,而是 OS 來做的。OS 根據局部性原理,會預讀部分的數據到內存緩存區,這樣下次 IO 如果讀取數據在緩存命中了,就不需要等待磁碟的定址,而是直接返回數據,效率就會快很多。
2.1.4 BufferedOutputStream
BufferedOutPutStream 也是 OutputStream 的具體實現類,相比於 FileOutputStream 優化了系統調優,即每次寫數據的時候,都會將數據放入緩存區中,等緩存區滿了之後,才會一次性寫入到磁碟中,大大提高了效率。
2.2 操作字元流數據
2.2.1 Reader
Reader 是實現字元輸入流的一種類型,其本身屬於一個抽象類,使用時需要使用具體的實現類。Reader 的實現類很多,針對不同的輸入設備都可以對應一個實現類,其中針對文件讀取的實現類是 FileReader。Reader 的使用方式和 InputStream 相仿。
示例代碼:
public class Demo2 {
public static void main(String[] args) throws FileNotFoundException {
File file = new File(“./test.txt”);
StringBuilder sb = new StringBuilder();
try (Reader reader = new FileReader(file)) {
while (true) {
int read = reader.read();
if (read == -1) {
break;
}
sb.append((char) read);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(sb.toString());
}
}
登錄後複製

2.2.2 Writer
Writer 是實現字元輸出流的一種類型,其本身屬於一個抽象類,使用時需要使用具體的實現類。Writer 的實現類很多,針對不同的輸出設備都可以對應一個實現類,其中針對文件讀取的實現類是 FileWriter。Writer 的使用方式和 OutputStream 相仿。
FileWriter 構造方法:
構造方法 說明
FileWriter(File file) 利用 File 構造對應文件輸出流
FileWriter(String name) 利用文件路徑構造對應文件輸出流
FileWriter(File file, boolean append) append 表示是否追加數據到文件的末尾,為 true 表示追加,為 false 表示情空之前的內容重新加入
FileWriter(String name, boolean append) append 表示是否追加數據到文件的末尾,為 true 表示追加,為 false 表示情空之前的內容重新加入
示例代碼:
public class Demo2 {
public static void main(String[] args) throws FileNotFoundException {
File in = new File(“./in.txt”);
File out = new File(“./out.txt”);
try (Reader reader = new FileReader(in);
Writer writer = new FileWriter(out)) {
while (true) {
int read = reader.read();
if (read == -1) {
break;
}
writer.write(read);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
登錄後複製

2.2.3 BufferedReader
BufferedReader 也是 Reader 的具體實現類,相比於 Reader 優化了系統調用,即通俗解釋為:將數據保存了緩存區,但是減少磁碟 IO 並不是 BufferedReader 來做的,而是 OS 來做的。OS 根據局部性原理,會預讀部分的數據到內存緩存區,這樣下次 IO 如果讀取數據在緩存命中了,就不需要等待磁碟的定址,而是直接返回數據,效率就會快很多。
2.2.4 BufferedWriter
BufferedWriter 也是 Writer 的具體實現類,相比於 Writer 優化了系統調優,即每次寫數據的時候,都會將數據放入緩存區中,等緩存區滿了之後,才會一次性寫入到磁碟中,大大提高了效率。
2.3 Scanner 和 PrintWriter
Java 標準庫中提供的 Scanner 和 PrintWriter 類能夠像文件中讀取文本數據和寫入文本數據。
2.3.1 Scanner
java.util.Scanner 類常用來從控制台中讀取字元串和基本類型的數值。Scanner 可以將輸入的值以空白字元分割標記。
Scanner 的構造方法:
構造方法 說明
Scanner(Readable source) 創建一個 Scanner,從指定的可讀資源中掃描標記,包括文件、文件路徑、字元串等。
Scanner(InputStream source) 創建一個 Scanner,從指定的位元組輸入流中掃把標記。
Scanner 常用方法:
方法 返回值類型 說明
hasNext() boolean 如果 Scanner 還要更多的數據可讀取,則返回 true
next() String 從 Scanner 中讀取下一個標記作為字元串返回
nextLine() String 從 Scanner 中讀取一行,以換行符結束
close() void 關閉 Scanner
System.in 為系統自帶的標準輸入流,該流是一直打開並準備提供輸入數據。通常,這個流對應於鍵盤輸入或由主機環境或用戶指定的另一個輸入源。
使用 Scanner 沒有必要關閉輸入文件,但是關閉能夠釋放文件佔有的資源。
示例代碼:
public class Demo3 {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(new File(“./test.txt”))) {
while (scanner.hasNext()) {
String s = scanner.next();
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
登錄後複製

2.3.2 PrintWriter
java.io.PrintWriter 類可用來創建一個文件並向文本文件中寫入數據。通常使用 System.out.println 向控制台輸入文本。
PrintWriter 構造方法:
構造方法 說明
PrintWriter(Writer out) 為指定的字元輸入流創建一個 PrintWriter。
PrintWriter(Writer out, boolean autoFlush) 為指定的字元輸入流創建一個 PrintWriter,如果 autoFlush 為 true,則 println、printf 或 format 方法將刷新輸出緩衝區。
PrintWriter(OutputStream out) 為指定的位元組輸入流創建一個 PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush) 為指定的位元組輸入流創建一個 PrintWriter,如果 autoFlush 為 true,則 println、printf 或 format 方法將刷新輸出緩衝區。
PrintWriter(String fileName) 為指定的文件路徑創建一個 PrintWriter
PrintWriter(String fileName, String csn) 為指定的文件路徑創建一個 PrintWriter,並且通過指定的字符集對字元進行編碼。
PrintWriter(File file) 為指定的文件對象創建一個 PrintWriter。
PrintWriter(File file, String scn) 為指定的文件對象創建一個 PrintWriter,並且通過指定的字符集對字元進行編碼。
PrintWriter 常用方法:
方法 返回值類型 說明
print(String s) void 將字元串寫入文件中
println(String s) void 將字元串寫入文件中,多列印一個換行
printf(String s) void 將字元串寫入文件中,按照指定格式寫文件中
System.out 為系統自帶的 printStream,表示控制台的標準 Java 對象,通過它能夠向控制台輸入數據。
使用 PrintWriter 必須使用 close 方法關閉文件,或者使用 try-with-resources 自動關閉資源,狗則數據就不能正確地保存在文件中。
示例代碼:
Java如何實現文件系統
package com.kiritor.util;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 文件的相關操作類
*
* @author Kiritor
*/
public class FileOperation {
private static String contentPath;
private static String filePath;
private static File[] fileList = null;// 保存文件列表,過濾掉目錄
public FileOperation() {
}
/** 構造函數的參數是一個目錄 */
public FileOperation(String path) {
File file = new File(path);
if (file.isDirectory())
this.contentPath = path;
else
this.filePath = path;
}
/**獲取文件列表*/
public static File[] getFiles() {
if (contentPath == null) {
File file = new File(filePath);
fileList = new File[1];
fileList[0] = file;
return fileList;
}
fileList = new File(contentPath).listFiles(new FileFilter() {
/**使用過濾器過濾掉目錄*/
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory())
{
return false;
}else
return true;
}
});
return fileList;
}
/** 對當前目錄下的所有文件進行排序 */
public static File[] sort() {
getFiles();
Arrays.sort(fileList, new FileComparator());
return fileList;
}
public static void tree(File f, int level) {
String preStr = “”;
for(int i=0; ilevel; i++) {
preStr += ” “;
}
File[] childs = f.listFiles();
//返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中的文件。
for(int i=0; ichilds.length; i++) {
System.out.println(preStr + childs[i].getName());
if(childs[i].isDirectory()) {
tree(childs[i], level + 1);
}
}
}
// 提供一個”比較器”
static class FileComparator implements java.util.ComparatorFile {
@Override
public int compare(File o1, File o2) {
// 按照文件名的字典順序進行比較
return o1.getName().compareTo(o2.getName());
}
}
}
使用java api調用HDFS文件系統時,遇到重複的代碼,怎麼解決
利用符集編碼。
因為HDFS支持6種字符集編碼,每個本地文件編碼方式又是極可能不一樣的,我們上傳本地文件的時候其實就是把文件編碼成位元組流上傳到文件系統存儲。
原創文章,作者:HAYN,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/133816.html