/**
* @author Mr.G
* @version 1.0
* @Description 输入输出示例
* @createTime 2021年10月19日 14:12:00
*/
public class FileputStremTest {
@Test
public void in() throws IOException {
InputStream in = new FileInputStream("a.txt");
byte[] bytes = new byte[1024];
int result ;
StringBuilder sb = new StringBuilder();
while ((result=in.read(bytes))!=-1){
sb.append(new String(bytes)); //往sb字符串里追加每次读的1024字节的内容,最后一次读多少,就追加的多少
}
System.out.println(sb);
in.close();
}
@Test
public void out() throws IOException {
//1可以在当前项目找写的位置
/*OutputStream os = new FileOutputStream("outzhuanyong.txt",true); //后面加一个boolean值:true追加。
String resources="what a nice girl!\r\n";
os.write(resources.getBytes());
os.close();*/
//2也可以 以物理盘上的地址
//OutputStream os = new FileOutputStream("d:\\test.txt");
//3还可以 以文件对象
OutputStream os = new FileOutputStream(new File("d:\\test.txt"));
String resources="what a pretty boy!111";
os.write(resources.getBytes()); //把指定的内容从内存写到外部硬盘的指定文件中。
os.close();
}
}
流:
内存与存储设置之间传输数据的管道。
如何区别
字节流 以stream结尾
字符流 以reader,writer结尾
应用场景:
1,读写二进制,字节缓冲流 BufferedOutputStream / BufferedInputStream
2,读写文本,字符缓冲流 BufferedWriter / BufferedReader
3,读写对象,对象流 ObjectOutputStream / ObjectInputStream
4,设置编码,转换流 OutputStreamWriter / InputStreamReader
节点流:从一个特定的数据源(节点)读写数据(如:文件、内存)的类叫做节点流类
这些节点类跟数据源或数据目的地做直接连接用的
过滤流(包装流)
按方向:
输入流。存储设备中内容读到内存中
输出流。内存数据——>存储设备
按单位:
字节流(读写所有数据)/字符流(只读写文本)
InputStream中的方法 :
int read(){};
int read(byte[] b){};
int read(byte[] b,int off,int len){};
OutputStream中的方法:
write(int n){};
write(byte[] b){};
write(byte[]b,int off,int len){};
FileInputStream read(byte[] b)//读取的内容存入数组b,返回读到字节数,到达尾部,返回-1.
FileOutputStream //将b中字节写入输出流。
按功能:
节点流:FileInputStream / FileOutputStream
//内存写到外存(存储介质)
FileOutputStream fos = new FileOutputStream("d://b.txt"); //!!!没有write(byte[])也会在文件夹中创建空文档。
fos.write("michael jackson".getBytes()); //再写一次会把原来的覆盖fos.write("hellofage".getBytes()); //把指定的内容从内存写到外部硬盘的指定文件中。
//外存写入到内存中
FileInputStream fis = new FileInputStream("d://a.txt");
byte[] b = new byte[1024]; //读到的数据
int length = fis.read(b); //读到的长度
System.out.println(length);
System.out.println("=================");
System.out.println(new String(b));
IO流拷贝:
//read()表示每次读取一个字节。
//read(byte [n])每次读n个字节.
//read(byte[n],0.length)是更严谨的,区别是最后一次也是写入相应的长度。
FileInputStream fis = new FileInputStream("a.mp4");
FileOutputStream fos=new FileOutputStream("b.mp4");
int length;
while ((length=fis.read()) !=-1){
fos.write(length);
}
IOUtils.closeAll(fis,fos);
//使用数组缓存
FileInputStream fis = new FileInputStream("a.mp4");
FileOutputStream fos=new FileOutputStream("b.mp4");
int length;
byte[] b = new byte[1024]; //1KB的数组
while ((length=fis.read(b))!=-1){ //length是变的,最后一次多少是多少。
fos.write(b);
}
IOUtils.closeAll(fis,fos);
//reaad(),write()中的length。
FileInputStream fis = new FileInputStream("d://a.mp4");
FileOutputStream fos=new FileOutputStream("d://b.mp4");
int length;
byte[] b = new byte[1024*5]; //5KB大小的缓存
while ((length=fis.read(b,0,1024))!=-1){ //每次读1024B
System.out.println(length);
fos.write(b,0,length); //每次写也是1024B
}
fis.close();
fos.close();
字节过滤流:BufferedInputStream / BufferedOutputStream 内存中的缓冲区
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
byte[] b = new byte[1024];
int length;
while ((length=bis.read(b))!=-1){
System.out.println(new String(b,0,length));
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
bis.close();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));
bos.write("hello.fage!".getBytes());
//bos.flush(); //刷新缓冲区
bos.close(); //刷新缓冲区+关流
对象流:ObjectInputStream / ObjectOutputStream 注意对象要实现Serializable 标记接口
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(new String("fageyes"));
oos.close(); //容易空指针异常
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
String o= (String) ois.readObject();
System.out.println(o);
ois.close();
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student implements Serializable {
private String name;
private Integer age;
public Student(String name) {
this.name = name;
}
}
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
Student stu = new Student("fage");
oos.writeObject(stu);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
Student o= (Student) ois.readObject();
System.out.println(o);
ois.close();
多个对象读写,如果个数没对上会报错,可用try{}catch()finally{}捕获或者List接收。
不希望被序列化的属性,要加上transient或者static
public class Student implements Serializable {
private transient String name; //或者static
private Integer age;
public Student(String name) {
this.name = name;
}
}
字符编码: UTF-8:针对Unicode可变长度字符编码 ISO-8859-1:收录除了ASCII外的其它编码 GBK: 简体中文,扩充 BIG5 :台湾,繁体中文
读写编码一样的话,就不会有中文乱码。
字符流:针对文本 Reader Writer
字符节点流:FileWriter FileReader
自身没有派生的方法,全靠继承而来, 富二代流
/**
* @author Mr.Gao
* @version 1.0
* @date 2021/4/10 10:44
*/
public class Test1 {
@Test
public void test1() throws IOException {
FileWriter fw = new FileWriter("a.txt");
fw.write("hello,fage!");
fw.close();
}
@Test
public void read() throws IOException {
FileReader fr = new FileReader("a.txt");
char[] c = new char[1024];
int len = fr.read(c);
System.out.println(new String(c,0,len));
}
}
字符过滤流 比 字节过滤流 更快。 因为每次读取一个字符。一字符2字节
/**单元测试类
* @author Mr.Gao
* @version 1.0
* @date 2021/4/10 10:44
*/
public class Test1 {
//字符过滤流/缓冲流
@Test
public void test1() throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
for (int i = 0; i < 5; i++) {
bw.write("hello,fage");
bw.newLine();//换行
}
bw.close();
}
@Test
public void test2() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String s;
while ((s=br.readLine())!=null){ //readLine()方法,一行行的读。返回的就是读到的string字符串。
System.out.println(s);
}
br.close();
}
}
打印字符流:printWriter
@Test
public void test1() throws IOException {
PrintWriter pw = new PrintWriter("a.txt");
pw.println("hello,fage1"); //pw.write()不可以换行
pw.println("hello,fage2");
pw.println(666);
pw.close();
}
字符转换流:OutputStreamWriter InputStreamReader
/**pw只有输出。。
* @author Mr.Gao
* @version 1.0
* @date 2021/4/10 10:44
*/
public class Test1 {
@Test
public void test1() throws IOException {//字符流包裹了字节流。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
osw.write("hello,fageboy");
osw.close();
}
@Test
public void test2() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
char[] c = new char[1024];
int len = isr.read(c);
System.out.println(new String(c,0,len));
isr.close();
}
}
//设置编码,防止中文乱码。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),"UTF-8");
****
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"UTF-8");
File类 物理盘符中的一个文件或文件夹
常用方法:
file.isDirectory();
file.createNewFile()
file.mkdirs() //针对多级文件夹。
file.mkdir()
file.getPath() //相对路径
f.getAbsoluteFile()
f.exists()
f.listFiles()
f.getParentFile() //返回此抽象路径名的父抽象路径名
File f = new File("a/b");
if (!f.exists()){
f.mkdirs();
}
File file=new File("a/b/a.txt");
if (!file.exists()){
boolean newFile = file.createNewFile();
System.out.println(newFile);
}else {
System.out.println("a/b/a.txt文件已经存在");
}
以上代码等效于:
注意:多级文件。要先看父目录存在不,再创建文件。
File file = new File("a/b/a.txt");
File pFile = file.getParentFile();
if (!pFile.exists()){
boolean mkdirs = pFile.mkdirs();
System.out.println(pFile+"文件父亲路径创建成功");
}
if (!file.exists()){
boolean newFile = file.createNewFile();
System.out.println(file.getAbsolutePath()+"文件创建成功");
}
System.out.println(file.getPath());
Java的绝对路径和相对路径
转义字符
概念:通过 \ 来转变后面字母或符号的含义。
举一些例子:
\b:退格
\n:换行
\t:制表符,相当于tab键
\r:回车
\:表示反斜杠
\’:表示单引号
\":表示双引号
以根部件开始的路径是绝对路径,比如/(Linux系统中)或者C:\(Windows系统中)。默认文件系统的路径分隔符,类Unix文件系统是/,Windows是
其实就是在硬盘上真正的路径,(URL和物理路径)例如:
C:\xyz\test.txt 代表了test.txt文件的绝对路径。http://www.sun.com/index.htm也代表了一个URL绝对路径。
相对路径: 相对于某个基准目录的路径。包含Web的相对路径(HTML中的相对目录),例如:在Servlet中,”/”代表Web应用的根目录,”./” 代表当前目录,“…/”代表上级目录。
归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是API在底层帮助我们构建了绝对路径,从而找到资源的!
4. 相对路径的几种使用情况
1.若引用的资源和本身在同一路径下(既在同一目录下),直接:
< img src=“tupian.gif” border=“0”/>
2.要引用的文件在下一级文件夹下,文件名前加子文件夹名称
假设info.html路径是:c:\Inetpub\wwwroot\sites\blabla\info.html
假设index.html路径是:c:\Inetpub\wwwroot\sites\blabla\html\tutorials\index.html
在info.html加入index.html超链接的href应该这样写:html/tutorials/index.html
3.要引用的文件在上一级文件夹下,文件名前加…/
假设info.html路径是:c:\Inetpub\wwwroot\sites\blabla\info.html
假设index.html路径是:c:\Inetpub\wwwroot\sites\index.html
在info.html加入index.html超链接的代码应该这样写:
index.html
举一反三: …/表示源文件所在目录的上一级目录,…/…/表示源文件所在目录的上上级目录,以此类推
4.更复杂的情况:
假设info.html路径是:c:\Inetpub\wwwroot\sites\blabla\info.html
假设index.html路径是:c:\Inetpub\wwwroot\sites\html\index.html
在info.html加入index.html超链接的代码应该这样写:index.html
5.最后一个例子
假设路径:D:\例子\html\style\view\pop.css
D:\例子\html\images\view\tupian.gif
在css中引用这个图片: < img src="…/…/images/view/tupian.gif" border=“0”/>
在JSP/HTML等页面引用CSS,Javascript.Action等属性时,前面可以加上< %=request.getContextPath()%>,以确保所引用的文件都属于Web应用所在目录。因为当使用类似”.”,”./”,”…/…/”等相对路径时,文件移动很容易出问题,但对于目录结构不变的应用影响不大。