操作圖片數據,就要用到字節流:InputStream(讀),OutputStream(寫)
1.用字節讀寫流讀寫一個文件
import java.io.*;
class FileStream
{
public static void main(String[] args) throws IOException
{
writeFile();
readFile_2();
}
public static void readFile() throws IOException
{
FileInputStream fis=new FileInputStream("fos.txt");
int ch=0;
while((ch=fis.read())!=-1)
{
System.out.println((char)ch);//一個字節一個字節的讀
}
fis.close();
}
public static void readFile_1() throws IOException
{
FileInputStream fis=new FileInputStream("fos.txt");
byte[] buf=new byte[1024];//創建字節數組
int len=0;
while((len=fis.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));//將字節數組整組一起讀出來
}
fis.close();
}
public static void readFile_2() throws IOException
{
FileInputStream fis=new FileInputStream("fos.txt");
int num=fis.available();
byte[] buf=new byte[num];//創建一個剛剛好的數組緩衝區
System.out.println(num);
fis.read(buf);//數組緩衝區剛好合適,就不用循環了
System.out.println(new String(buf));
fis.close();
}
public static void writeFile() throws IOException
{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());
fos.close();
}
}
練習:複製一張圖片
步驟:用字節讀取流對象和圖片關聯
用字節寫入流創建一個圖片文件,用於存儲獲取到的圖片數據
通過循環讀寫,完成數據的存儲
關閉資源
import java.io.*;
class CopyPicture
{
public static void main(String[] args)
{
FileOutputStream fos=null;
FileInputStream fis=null;
try
{
fos=new FileOutputStream("e:\\p2.jpg");
fis=new FileInputStream("c:\\p1.jpg");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("複製文件失敗");
}
finally
{
try
{
if(fis!=null)
fis.close();
}
catch(IOException e)
{
System.out.println(e.toString());
}
try
{
if(fos!=null)
fos.close();
}
catch(IOException e)
{
System.out.println(e.toString());
}
}
}
}
對於字節流的緩衝區,通過複製Mp3來演示
import java.io.*;
class CopyMusic
{
public static void main(String[] args)throws IOException
{
long start=System.currentTimeMillis();//拷貝開始時間
copy_1();
long end=System.currentTimeMillis();//拷貝結束時間
System.out.println(end-start);
}
public static void copy_1() throws IOException
{
FileInputStream fis=new FileInputStream("e:\\feng.mp3");
FileOutputStream fos=new FileOutputStream("c:\\feng1.mp3");
//建立字節緩衝區,並把流對象存入
BufferedInputStream bufi=new BufferedInputStream(fis);
BufferedOutputStream bufo=new BufferedOutputStream(fos);
int by=0;
while((by=bufi.read())!=-1)//當沒有讀取到字節流的末尾時
{
bufo.write(by);//寫入字節緩衝區中
}
//關閉流資源
bufi.close();
bufo.close();
}
}
自定義一個字節緩衝區
import java.io.*;
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf=new byte[1024*4];
private int pos=0,count=0;
MyBufferedInputStream(InputStream in)
{
this.in=in;
}
//一次讀一個字符,從緩衝區獲取
public int MyRead() throws IOException
{
if(count==0)
{
count=in.read(buf);//通過in對象讀取硬盤上的數據,並存入buf中,用count計數讀的個數
if(count<0)
return -1;
pos=0;
byte b=buf[pos];//取0角標元素,即第一個元素
count--;
pos++;
return b&255;
/*
讀到的頭8個字節是111-11111,即爲-1,如此在循環中就符合條件,會讓虛擬機誤以爲是已經到了數據流的末尾,
而返回值是int型就可以將字節提升,變成111-11111 111-11111 111-11111 111-11111,這樣將-1前面的值補0
即0000-0000 0000-0000 0000-0000 111-11111這樣既可以提升字節,還可以避免與判斷位的-1相同,可以繼續循環
而不會出現複製的音樂文件是0kb了,所以返回時,b&255就會將byte提升爲int時,前面補0
*/
}
else if(count>0)//取出剩下的元素
{
byte b=buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myclose() throws IOException
{
in.close();
}
}
讀取鍵盤錄入數據
import java.io.*;
class ReadIn
{
public static void main(String[] args) throws IOException
{
InputStream in =System.in;//獲取鍵盤錄入對象
StringBuilder sb=new StringBuilder(in);建立字符緩衝區
while(true)
{
int ch=in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s=sb.toString();
if("over".equals(s))//如果輸入的是“over”,則停止
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length()); //發現鍵盤不斷輸入的時候,字符串越來越長,
//所以需要執行該動作在完成一次打印後就清空緩衝區
}
else
sb.append((char)ch);
}
in.close();
}
}
轉換流:InputStreamReader 將字節流對象轉換成字符流,OutputStreamWriter將字符流對象轉換成字節流
注意:當涉及到字符編碼轉換時需要用到轉換流,操作的文件字節輸出流:FileOutputStream
import java.io.*;
class TransStreamDemo
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;//獲取鍵盤錄入對象
InputStreamReader isr=new InputStreamReader(in);//用轉換流InputStreamReader將字節流對象轉換成字符流對象,
BufferedReader bufr=new BufferedReader(isr);//爲了提高效率,對字符串使用緩衝區技術,
OutputStream out=System.out;//獲取控制檯輸出對象
OutputStreamWriter osw=new OutputStreamWriter(out);//使用轉換流將字符流轉換成字節流
BufferedWriter bufw=new BufferedWriter(osw); //使用緩衝區技術,提高效率
//開始循環,輸出字符流數據
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();//轉行
bufw.flush();//刷新
}
bufr.close();
}
}
流操作的基本規律:通過三個明確來完成
明確源和目的
源:輸入流,InputStream Reader
目的:輸出流,OutputStream Writer
操作的數據是否爲純文本
是:字符流;否:字節流
當體系明確後,再明確要使用哪個具體的對象
通過設備來進行區分:源設備:內存,硬盤,鍵盤
目的設備:內存,硬盤,控制檯
改變標準輸入輸出設備System.setIn(new FileInputStream("demo.java")); System.setout(new PrintStream("z.txt"))
異常處理日誌的建立
import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[] args)
{
try
{
int[] arr= new int[2];
System.out.println(arr[3]);
}
catch(Exception e)
{
try
{
Date d=new Date();//創建時間對象
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//創建格式化時間的對象
String s=sdf.format(d);將時間傳入到格式對象中
PrintStream ps=new PrintStream("exeception.log");
ps.println(s);
System.setOut(ps); //重置目的對象,便於記錄異常事件
}
catch(IOException e1)
{
throw new RuntimeException("日誌文件創建失敗");
}
e.printStackTrace(new PrintStream(System.out));//將異常記錄到文件中
}
}
}
import java.util.*;
import java.io.*;
class SystemInfo
{
public static void main(String[] args) throws IOException
{
Properties prop=System.getProperties();//獲取系統的屬性信息
//System.out.println(prop);
prop.list(new PrintStream("sys.txt"));//在打印流中創建文本文檔保存系統信息
}
}