為什么叫原生IO,也就是后續有更加強大的NIO、AIO操作,但原生IO是基礎,先學習一下!
IO流的概念
前面介紹JavaAPI的時候,只是對目錄/檔案進行操作,而具體的內容操作就需要IO流
I/O的全稱是Input/Output,顧名思義就是用來設備之間傳輸資料的
io的示意圖

分類

io體系


乍一看分類太雜了,但是如果作為初學者不用全部掌握,掌握幾個流的操作方法,其它的流操作也是大同小異!
基本使用步驟
之前在介紹JavaAPI的時候介紹過File類的含義,我們進行IO操作的時候,就是依靠這個File類,先去創建它的物件!
輸入:
-
創建File類的物件,指定讀取資料的來源
-
創建對應的輸入流物件,將File類的物件作為引數
-
傳輸資料,創建相應的byte[] 或 char[],
-
關閉流物件(占用系統資源)
輸出:
-
創建File類的物件,指定讀取資料的來源,檔案不存在時會進行創建
-
創建對應的輸入流物件,將File類的物件作為引數
-
傳輸資料,write(char[]/byte[] buffer,0,len)
-
關閉流物件(占用系統資源)
輸入流
位元組流
主要操作的是抽象類InputStream的子類,看InputStream的描述
/**
* This abstract class is the superclass of all classes representing
* an input stream of bytes.
*
* <p> Applications that need to define a subclass of <code>InputStream</code>
* must always provide a method that returns the next byte of input.
*
* 此抽象類表示所有位元組輸入流類的超類
* InputStream的子類應用程式需要提供一個輸入位元組的方法,
*/
public abstract class InputStream implements Closeable {
//讀取資料的方法
public abstract int read() throws IOException; //一個一個位元組進行讀取,讀到最后一個位元組之后回傳-1
public int read(byte b[]) throws IOException{} //讀取陣列長度的位元組
public int read(byte b[], int off, int len) throws IOException{}
public class TestFileInputsream {
public static void main(String[] args) throws IOException {
//1、創建源檔案物件
File file = new File("F:\\test.txt");
//2、創建源檔案到程式的輸出流物件
InputStream inputStream = new FileInputStream(file);
//3、讀取源檔案
int read = inputStream.read(); //一個一個位元組進行讀取,讀到最后一個位元組之后回傳-1
while (read != -1) {
System.out.print((char) read);
read = inputStream.read();
}
//4、關閉輸出流物件
inputStream.close();
}
}
package com.ty.inputstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class TestFileInputsream2 {
public static void main(String[] args) throws IOException {
//1、創建源檔案物件
File file = new File("F:\\test.txt");
//2、創建源檔案到程式的輸出流物件
InputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[1024]; //利用緩沖陣列,開辟1024個空間
//3、讀取源檔案,讀取陣列長度的位元組
int read = inputStream.read(bytes);
while (read != -1) {
for (int i = 0; i < read; i++) {
System.out.print((char) bytes[i]);
}
read = inputStream.read();
}
//4、關閉輸出流物件
inputStream.close();
}
}
System.in
前面在常用的API介紹過System是一個工具類,而System.in此時得到的其實是一個標準的輸入流,而且是一個位元組流
/**
* The "standard" input stream. This stream is already
* open and ready to supply input data. Typically this stream
* corresponds to keyboard input or another input source specified by
* the host environment or user.
*
* “標準”輸入流,該流已經打開,可以提供輸入資料了,通常,此流對應于鍵盤輸入或主機環境和用戶指定的另一個輸入源,
*/
public final static InputStream in = null;
public class TestSystemIn {
public static void main(String[] args) throws IOException {
/*
* InputStream in = System.in;
* int read = in.read();//read方法等待鍵盤的錄入,是一個阻塞方法,
* System.out.println(read);
*/
/**從鍵盤錄一個資料
* Scanner 掃描器,掃描鍵盤到程式的那個輸入流
* 還可以掃描其他流,比如:Scanner sc=new Scanner(new FileInputStream(new File("F:\\test.txt")));
*/
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
System.out.println(num);
Scanner sc=new Scanner(new FileInputStream(new File("F:\\test.txt")));
while (sc.hasNext()){
System.out.println(sc.next());
}
}
}
字符流
主要操作的是抽象類Reader的子類,看Reader的描述
/**
* Abstract class for reading character streams. The only methods that a
* subclass must implement are read(char[], int, int) and close(). Most
* subclasses, however, will override some of the methods defined here in order
* to provide higher efficiency, additional functionality, or both.
*
* 讀取字符流的抽象類, 子類必須實作的唯一方法是read(char [],int,int)和close(),
* 但是,大多數子類將覆寫此處定義的某些方法,以提供更高的效率和/或附加功能,
*/
public abstract class Reader implements Readable, Closeable {
//讀取資料的方法
public int read() throws IOException{}
public int read(char cbuf[]) throws IOException{}
abstract public int read(char cbuf[], int off, int len) throws IOException;
public class TestFileReader {
public static void main(String[] args) throws IOException {
//1、創建源檔案物件
File file = new File("F:\\test.txt");
//2、創建源檔案到程式的輸出流物件
Reader reader = new FileReader(file);
//3、讀取源檔案,一個一個字符進行讀取
int read = reader.read();
while (read != -1) {
System.out.print((char) read);
read = reader.read();
}
//4、關閉輸出流物件
reader.close();
}
}
public class TestFileReader2 {
public static void main(String[] args) throws IOException {
//1、創建源檔案物件
File file = new File("F:\\test.txt");
//2、創建源檔案到程式的輸出流物件
Reader reader = new FileReader(file);
char[] chars=new char[1024];
//3、讀取源檔案,讀取陣列長度的字符
int read = reader.read(chars);
while (read != -1) {
// for (int i = 0; i < read; i++) {
// System.out.print(chars[i]);
// }
System.out.print(new String(chars,0,read)); //將陣列轉為String
read=reader.read(chars);
}
//4、關閉輸出流物件
reader.close();
}
}
輸出流
位元組流
主要操作的是抽象類OutputStream的子類,看OutputStream的描述
/**
* This abstract class is the superclass of all classes representing
* an output stream of bytes. An output stream accepts output bytes
* and sends them to some sink.
* <p>
* Applications that need to define a subclass of
* <code>OutputStream</code> must always provide at least a method
* that writes one byte of output.
*
* 此抽象類表示所有位元組輸出流類的超類,
* OutputStream的子類應用程式需要提供一種回傳一個位元組輸出的方法,
*/
public abstract class OutputStream implements Closeable, Flushable {
//輸出資料的方法
public abstract void write(int b) throws IOException;//把資料輸出到檔案中,一個一個位元組輸出位元組
public void write(byte b[]) throws IOException{} //輸出位元組長度的位元組
public void write(byte b[], int off, int len) throws IOException{} //輸出位元組長度的位元組,從off開始長度為len
public class TestFileOutputStream {
public static void main(String[] args) throws IOException {
//1、創建目標檔案
File file=new File("F:\\demo.txt");
//2、創建程式到目標檔案的輸出流,這種情況前面指定的目標檔案時如果不存在則會進行創建
OutputStream outputStream=new FileOutputStream(file);
//OutputStream outputStream=new FileOutputStream(file,true);默認會對檔案進行覆寫,這樣會對檔案進行追加
String str="hello";
byte[] bytes = str.getBytes();
for (byte b : bytes) {
//3、把資料輸出到檔案中
outputStream.write(b);
}
//4、關閉輸出流
outputStream.close();
}
}
public class TestFileOutputStream2 {
public static void main(String[] args) throws IOException {
//1、創建目標檔案
File file=new File("F:\\demo.txt");
//2、創建程式到目標檔案的輸出流,這種情況前面指定的目標檔案時如果不存在則會進行創建
OutputStream outputStream=new FileOutputStream(file);
String str="hello,world";
byte[] bytes = str.getBytes();
//3、把資料輸出到檔案中,以位元組長度輸出到檔案
outputStream.write(bytes);
//4、關閉輸出流
outputStream.close();
}
}
System.out
此時回傳的是一個輸出流 、 列印流(PrintStream)
/**
* The "standard" output stream. This stream is already
* open and ready to accept output data. Typically this stream
* corresponds to display output or another output destination
* specified by the host environment or user.
* <p>
* For simple stand-alone Java applications, a typical way to write
* a line of output data is:
* <blockquote><pre>
* System.out.println(data)
* </pre></blockquote>
* <p>
* See the <code>println</code> methods in class <code>PrintStream</code>.
*
* “標準”輸出流, 該流已經打開,并準備接受輸出資料,通常,此流對應于主機環境或用戶指定的顯示輸出或另一個輸出目標,
* 對于簡單的獨立Java應用程式,寫一行輸出資料的典型方法是:System.out.println(data)
* 請參見類PrintStream的print方法,
*/
public final static PrintStream out = null;
public class TestSystemOut {
public static void main(String[] args) {
PrintStream out = System.out;
out.println("hello"); // System.out.println("hello"),輸出之后換行
out.print("hello,world"); // System.out.print("hello,world"),直接輸出
}
}
字符流
主要操作的是抽象類Writer的子類,看Writer的描述
/**
* Abstract class for writing to character streams. The only methods that a
* subclass must implement are write(char[], int, int), flush(), and close().
* Most subclasses, however, will override some of the methods defined here in
* order to provide higher efficiency, additional functionality, or both.
*
* 寫入字符流的抽象類,子類必須實作的唯一方法是write(char [],int,int),flush()和close(),
* 但是,大多數子類將覆寫此處定義的某些方法,以提供更高的效率和/或附加功能,
*/
public abstract class Writer implements Appendable, Closeable, Flushable {
//輸出資料的方法
public void write(int c) throws IOException{}
public void write(char cbuf[]) throws IOException{}
abstract public void write(char cbuf[], int off, int len) throws IOException;
public void write(String str) throws IOException{}
public class TestFileWriter {
public static void main(String[] args) throws IOException {
//創建程式到目標檔案的輸出流,創建目標檔案,
Writer writer=new FileWriter(new File("F:\\demo.txt"));
String str="夜曲";
for (int i = 0; i < str.length(); i++) {
//把資料輸出到檔案中
writer.write(str.charAt(i));
}
writer.write(str,0,str.length());
writer.write("我的夢!");
//關閉輸出流
writer.close();
}
}
public class TestFileWriter2 {
public static void main(String[] args) throws IOException {
Writer writer=new FileWriter(new File("F:\\demo.txt"));
String str="夜曲";
char[] chars=str.toCharArray();
writer.write(chars);
writer.close();
}
}
復制文本
public class CopyText {
public static void main(String[] args) throws IOException {
Reader reader = new FileReader(new File("F:\\a.txt"));
Writer writer = new FileWriter(new File("F:\\b.txt"));
char[] chars = new char[1024];
int read = reader.read(chars);
while (read != -1) {
writer.write(chars, 0, read);
read = reader.read(chars);
}
//關閉流的流程:先用后關
writer.close();
reader.close();
}
}
處理流
處理流就是在普通流也就是節點流的基礎再嵌套一個流!
緩沖流
緩沖區(Buffered):BufferedOutputStream/BufferInputStream;字符:BufferedReader/BufferedWriter
-
提高IO效率,減少訪問磁盤的次數
-
資料存盤在緩沖區中,flush是將快取區的內容寫入檔案中,也可以直接close

public class TestInputStream {
public static void main(String[] args) throws IOException {
File file = new File("F:\\test.txt");
InputStream inputStream = new FileInputStream(file);
//在FileInputStream的基礎上套用一個BufferedInputStream
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] bytes = new byte[1024 * 10];
int read = bufferedInputStream.read(bytes);
while (read != -1) {
for (int i = 0; i < read; i++) {
System.out.println((char) bytes[i]);
}
read = bufferedInputStream.read(bytes);
}
bufferedInputStream.close();
}
}
復制圖片
public class CopyPicture {
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream(new File("F:\\test.jpg"));
OutputStream outputStream = new FileOutputStream(new File("F:\\copy.jpg"));
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
byte[] chars = new byte[1024 * 10];
int read = bufferedInputStream.read(chars);
while (read != -1) {
bufferedOutputStream.write(chars, 0, read);
bufferedOutputStream.flush();
read = bufferedInputStream.read(chars);
}
bufferedOutputStream.close();
bufferedInputStream.close();
}
}
復制檔案夾
public class CopyDir {
public static void main(String[] args) {
//copyFile(new File("F:/a.txt"), new File("F:/b.txt"));
copyDir(new File("F:/a"), new File("F:/b"));
}
//復制檔案夾
public static void copyDir(File srcFile, File targetFile) {
if (!targetFile.exists()) {
targetFile.mkdirs();
}
File[] files = srcFile.listFiles();
for (File file : files) {
if (file.isDirectory()) {
copyDir(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName())
);
}
if (file.isFile()) {
copyFile(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName()));
}
}
}
//復制檔案
public static void copyFile(File srcFile, File targetFile) {
BufferedInputStream inputStream = null;
BufferedOutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(srcFile));
outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));
byte[] bytes = new byte[1024 * 8];
int read = inputStream.read(bytes);
while (read != -1) {
outputStream.write(bytes, 0, read);
read = inputStream.read(bytes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
通常我們進行io操作,例外不會向上拋,只會處理例外,但上面代碼處理例外看的有些累贅!用上之前在例外章節說得try-resource寫法
public class CopyDir {
public static void main(String[] args) {
copyDir(new File("F:/a"), new File("F:/b"));
}
//復制檔案夾
public static void copyDir(File srcFile, File targetFile) {
if (!targetFile.exists()) {
targetFile.mkdirs();
}
File[] files = srcFile.listFiles();
for (File file : files) {
if (file.isDirectory()) {
copyDir(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName())
);
}
if (file.isFile()) {
copyFile(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName()));
}
}
}
//復制檔案
public static void copyFile(File srcFile, File targetFile) {
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));) {
byte[] bytes = new byte[1024 * 8];
int read = inputStream.read(bytes);
while (read != -1) {
outputStream.write(bytes, 0, read);
read = inputStream.read(bytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
關閉io代碼都不用我們處理了,其實是底層幫我們處理的,看反編譯之后的class
public class CopyDir
{
public static void main(String[] args)
{
copyDir(new File("F:/c"), new File("F:/d"));
}
public static void copyDir(File srcFile, File targetFile)
{
if (!targetFile.exists()) {
targetFile.mkdirs();
}
File[] files = srcFile.listFiles();
for (File file : files) {
if (file.isDirectory()) {
copyDir(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName()));
}
if (file.isFile())
copyFile(new File(srcFile + File.separator + file.getName()), new File(targetFile + File.separator + file.getName()));
}
}
public static void copyFile(File srcFile, File targetFile)
{
try {
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile)); Throwable localThrowable6 = null;
try { BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));
Throwable localThrowable7 = null;
try {
byte[] bytes = new byte[8192];
int read = inputStream.read(bytes);
while (read != -1) {
outputStream.write(bytes, 0, read);
read = inputStream.read(bytes);
}
}
catch (Throwable localThrowable1)
{
localThrowable7 = localThrowable1; throw localThrowable1;
}
finally
{
if (outputStream != null) if (localThrowable7 != null) try { outputStream.close(); } catch (Throwable localThrowable2) { localThrowable7.addSuppressed(localThrowable2); } else outputStream.close();
}
}
catch (Throwable localThrowable4)
{
localThrowable6 = localThrowable4; throw localThrowable4;
}
finally
{
if (inputStream != null) if (localThrowable6 != null) try { inputStream.close(); } catch (Throwable localThrowable5) { localThrowable6.addSuppressed(localThrowable5); } else inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
轉換流
主要操作的是InputStreamReader/OutputStreamWriter類
/**
* An InputStreamReader is a bridge from byte streams to character streams: It
* reads bytes and decodes them into characters using a specified {@link
* java.nio.charset.Charset charset}. The charset that it uses
* may be specified by name or may be given explicitly, or the platform's
* default charset may be accepted.
*
* InputStreamReader是從位元組流到字符流的橋梁:它讀取位元組,并使用指定的charset它們解碼為charset ,
* 它使用的字符集可以通過名稱指定,也可以顯式指定,或者可以接受平臺的默認字符集,
*/
public class InputStreamReader extends Reader {
/**
* An OutputStreamWriter is a bridge from character streams to byte streams:
* Characters written to it are encoded into bytes using a specified {@link
* java.nio.charset.Charset charset}. The charset that it uses
* may be specified by name or may be given explicitly, or the platform's
* default charset may be accepted.
*
* OutputStreamWriter是從字符流到位元組流的橋梁:寫入到字符流的字符使用指定的charset編碼為位元組,
* 它使用的字符集可以通過名稱指定,也可以顯式指定,或者可以接受平臺的默認字符集,
*/
public class TestInputStreamReader {
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream(new File("F:/test.txt"));
/**需要指定一個編碼格式,如果不指定則按照開發工具的編碼格式進行轉換
* 如果轉換格式不統一就會亂碼
*/
InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(reader);
char[] chars = new char[1024 * 10];
int read = bufferedReader.read(chars);
while (read != -1) {
for (int i = 0; i < read; i++) {
System.out.print(chars[i]);
}
read = bufferedReader.read(chars);
}
bufferedReader.close();
}
}
public class Copy {
public static void main(String[] args) throws IOException {
InputStreamReader reader=new InputStreamReader(new FileInputStream(new File("F:\\test.txt")));
OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream(new File("F:\\copy.txt")));
BufferedReader bufferedReader=new BufferedReader(reader);
BufferedWriter bufferedWriter=new BufferedWriter(writer);
char[] chars=new char[1024*10];
int read = bufferedReader.read(chars);
while (read!=-1){
bufferedWriter.write(chars);
read = bufferedReader.read(chars);
}
bufferedWriter.close();
bufferedReader.close();
}
}
鍵盤輸入到文本
public class InputToText {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(new File("F:\\text.txt")));
BufferedReader bufferedReader = new BufferedReader(reader);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
String str = bufferedReader.readLine();
while (!"exit".equals(str)) {
bufferedWriter.write(str);
bufferedWriter.newLine();
str = bufferedReader.readLine();
}
bufferedWriter.close();
bufferedReader.close();
}
}
資料流
用來操作基本資料型別和字串的,主要操作DataInputStream和DataOutputStream類
/**
* A data input stream lets an application read primitive Java data
* types from an underlying input stream in a machine-independent
* way. An application uses a data output stream to write data that
* can later be read by a data input stream.
* <p>
* DataInputStream is not necessarily safe for multithreaded access.
* Thread safety is optional and is the responsibility of users of
* methods in this class.
*
* 資料輸入流允許應用程式以與機器無關的方式從基礎輸入流中讀取原始Java資料型別,
* 應用程式使用資料輸出流來寫入資料,以后可以由資料輸入流讀取,
* DataInputStream對于多執行緒訪問不一定是安全的,執行緒安全是可選的,并且是此類中用戶的責任
* DataInputStream:將檔案中存盤的基本資料型別和字串寫入記憶體的變數中
*/
public class DataInputStream extends FilterInputStream implements DataInput {
/**
* A data output stream lets an application write primitive Java data
* types to an output stream in a portable way. An application can
* then use a data input stream to read the data back in.
*
* 資料輸出流允許應用程式以可移植的方式將原始Java資料型別寫入輸出流,然后,應用程式可以使用資料輸入流來讀回資料,
* DataOutputStream:將記憶體中的基本資料型別和字串的變數寫出到檔案中
*/
public class DataOutputStream extends FilterOutputStream implements DataOutput {
public class TestDataOutputStream {
public static void main(String[] args) throws IOException {
//路徑不指定盤符是相對路徑,指代當前專案工程下
DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(new File("data.txt")));
outputStream.writeUTF("同一首歌!");
outputStream.write(66);
outputStream.writeBoolean(true);
outputStream.writeDouble(6.6);
outputStream.close();
// 檔案輸出:同一首歌!B@ffffff,這個不是給你看的,是給程式看的
}
}
public class TestDataInputStream {
public static void main(String[] args) throws IOException {
DataInputStream inputStream = new DataInputStream(new FileInputStream(new File("data.txt")));
//寫出的型別跟讀入的型別一一匹配!
System.out.println(inputStream.readUTF());
System.out.println(inputStream.read());
System.out.println(inputStream.readBoolean());
System.out.println(inputStream.readDouble());
inputStream.close();
}
}
物件流
可以把Java中的物件寫入到資料源中,也能把物件從資料源中還原回來,主要操作ObjectInputStream和ObjectOutputStream類
/**
* An ObjectInputStream deserializes primitive data and objects previously
* written using an ObjectOutputStream.
*
* ObjectInputStream反序列化以前使用ObjectOutputStream撰寫的原始資料和物件,
*/
public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants{
/**
* An ObjectOutputStream writes primitive data types and graphs of Java objects
*
* ObjectOutputStream將Java的原始資料型別和物件型別寫入OutputStream,
* 此操作也被稱為序列化
*/
物件序列化的細節:
- 必須實作Serializable介面
- serialVersionUID的作用:序列化版本號,保證更改序列化類的結構時,不會對反序列化結果產生影響
- 必須保證其所有屬性均可序列化
- 使用transient和static關鍵字修飾的屬性,不會參與序列化
public class User implements Serializable {
private static final long serialVersionUID = 7516451367496182472L;
private String userName;
private transient String password;
private static double balance;
private Integer number;
public User() {
}
public User(String userName, String password, Integer number) {
this.userName = userName;
this.password = password;
this.number = number;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static double getBalance() {
return balance;
}
public static void setBalance(double balance) {
User.balance = balance;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
@Override
public String toString() {
return "User{" +
"userName=" + userName +
", password='" + password + '\'' +
", number=" + number +
", balance=" + balance +
'}';
}
}
public class TestObjectOutputStream {
public static void main(String[] args) throws IOException {
ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream(new File("user.txt")));
User user=new User("jack","123456",17);
User.setBalance(8500.0);
System.out.println(user);
outputStream.writeObject(user);
outputStream.write(45);
outputStream.writeBoolean(true);
outputStream.close();
}
}
public class TestObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream(new File("user.txt")));
System.out.println(inputStream.readObject());
System.out.println(inputStream.read());
System.out.println(inputStream.readBoolean());
inputStream.close();
}
}
編碼格式
編碼分類
| 字符編碼 | 字符編碼介紹 |
|---|---|
| ISO-8856-1 | 收錄ASCII外,還包括西歐、希臘語、泰語、阿拉伯語、希伯來語對應的文字符號 |
| UTF-8 | 針對Unicode的可變長度字符編碼,Windows系統中文默認為3個位元組 |
| GB2312 | 簡體中文 |
| GBK | 簡體中文、擴充,Windows系統中文默認為2個位元組 |
| BIG5 | 臺灣,繁體中文 |
| 注意: | 當編碼方式和解碼方式不一致時,會出現亂碼 |
編碼和解碼轉換
public class TestEncoding {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "hello,歡迎";
//不傳字符集時,默認按照IDE的編碼
byte[] binary = str.getBytes("UTF-8"); //獲得字串的二進制表現形式:104 101 108 108 111 44 -26 -84 -94 -24 -65 -114
for (int i = 0; i < binary.length; i++) {
System.out.print(binary[i] + "\t");
}
String text=new String(binary,"gbk");
System.out.println(text); //hello,嬈㈣繋
//錯誤做法
byte[] bytes = str.getBytes("gbk");
String s = new String(bytes, "utf-8");
System.out.println(s);//輸出:hello,??? 亂碼那部分表示在UTF-8的編碼中沒有對應gbk的編碼
//正確做法,編碼和解碼保持一致
bytes=str.getBytes("utf-8");
s = new String(bytes, "utf-8");
System.out.println(s); //輸出:hello,歡迎
}
}
工具庫:commons-io
原生的io操作比較復雜,有一個工具庫可以簡化我們的操作就是Common IO
參考地址:http://commons.apache.org/proper/commons-io/index.html,可以查看使用的API
先引入commons-io的jar包,我們用maven引入,不會使用的話,手動下載之后導包也可以
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
public class TestCommon {
public static void main(String[] args) throws IOException {
long size = FileUtils.sizeOf(new File("F:\\c"));
System.out.println("檔案夾大小:" + size);
FileUtils.copyFile(new File("F:\\a\\test.txt"),new File("F:\\a\\copy.txt"));
FileUtils.write(new File("F:\\a\\test.txt"),"hello,Spring!");
}
}
ps:以上只是io體系的普通io,java有另一種io,即:NIO,是面向緩沖區的,所以會更高效,后續也是必學的!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231743.html
標籤:Java
