文章目录
- C++文件读写(举例):
- Java文件读写(举例):
- 1、通过FileInputStream与FileOutputStream文件输入输出流进行读写(以文本文件复制为例)
- 2、通过FileReader搭配BufferedReader、FileWriter搭配BufferedWriter进行读写(以文本文件复制为例)
- 3、Java I/O是典型的装饰模式,现在对一些类进行继承和重写来重新对Java I/O进行装饰改造。
- 4、文件复制(直接复制文件,使用文件流进行操作)(参考1)(这里对文本文档进行末尾添加操作,而不是覆盖已有内容)
- 5、从键盘读入写到文件内部(采用PrintStream写入文件)
- 6、从文件读入内容进行操作后(变换大小写,统计文件字符数、行数等)输出到新文件中并打印到屏幕上(BufferedReader读入,PrintStream写入)
- 7、以变量方式读取文件进行操作,使用Scanner读入(按格式),使用PrintStream写入(以计算学生成绩为例)
C++文件读写(举例):
参考:
2019年2月8日训练日记(文件操作知识点小结)
文件操作的详细使用
C++文件读写详解(ofstream,ifstream,fstream)
C/C++读写文件的几种方法fstream fopen、fwrite()、fread()操作
注意事项(乱码问题):
文件读写很容易乱码,在txt读取时文档格式为ANSI则不会在屏幕输出时乱码,如果txt文件为UTF-8格式则会导致屏幕输出时乱码。
参考:c++ txt文件的读写及乱码问题解决
1、通过ifstream与getline()函数进行读取;直接通过ifstream定义的infile进行重定向输入。
例一:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 1;
string tem;
ifstream infile("test.txt");
for(int i = 0; i<n; i++) //由getline()函数控制读到什么位置终止
{
/*
getline()函数 参考: C++ getline函数用法详解: http://c.biancheng.net/view/1345.html
getline() 语法:
istream &getline( char *buffer, streamsize num );
istream &getline( char *buffer, streamsize num, char delim );
getline()函数用于输入流,读取字符到buffer中,直到下列情况发生:
num - 1个字符已经读入,
碰到一个换行标志,
碰到一个EOF,
或者,任意地读入,直到读到字符delim。delim字符不会被放入buffer中。
*/
//getline(infile,tem);
//getline(infile,tem,'a'); //读到文件中第一个a停止(不包含a)
getline(infile,tem,' '); //默认读到 停止,由于文件中不存在 故读到文件末尾
cout<<tem.c_str(); //.c_str()以C风格方式输出字符串。
}
//由于是getline()函数控制读到什么位置终止,所以不写到for循环内也OK
//getline(infile,tem,' '); //默认读到 停止,由于文件中不存在 故读到文件末尾
//cout<<tem.c_str(); //.c_str()以C风格方式输出字符串。
//直接通过ifstream定义的infile进行重定向输入(格式不符合原文格式,需要注意格式问题)。
/*
while(infile>>tem){
cout<<tem.c_str()<<endl;
}
*/
return 0;
}
例二:
#include<bits/stdc++.h>
using namespace std;
int main()
{
char buffer[256];
ifstream in("test.txt");
if (! in.is_open())
{
cout << "Error opening file";
exit (1);
}
while (!in.eof() )
{
in.getline (buffer,100); //读到每一行的换行即停止
cout << buffer << endl;
}
return 0;
}
应用举例(可参考12306、图书管理系统):
void Gaotieop::load()
{
Gaotie g;
int gaotieshu_;
ifstream infile("2018212591马俊光的车次信息.txt",ios::in);
if(!infile)
{
cout<<"can't load Gaotie!"<<endl;
return;
}
vgaotie.clear();
gaotienumber.clear();
gaotiename.clear();
siteshu.clear();
infile>>gaotieshu_;
setGaotieshu(gaotieshu_);
for(int i=1;i<=gaotieshu_;i++)
{
infile>>g;
vgaotie.push_back(g);
gaotienumber.insert(make_pair(g.getNumber(),vgaotie.size()-1));
gaotiename.insert(make_pair(g.getName(),vgaotie.size()-1));
siteshu.insert(make_pair(g.getSiteshu(),vgaotie.size()-1));
}
infile.close();
//test
/*
cout<<getGaotieshu()<<endl;
for(int i=0;i<vgaotie.size();i++)
cout<<vgaotie[i];
*/
}
void Gaotieop::save()
{
ofstream outfile("2018212591马俊光的车次信息.txt",ios::out);
if(!outfile)
{
cout<<"can't save Gaotie!"<<endl;
return;
}
outfile<<getGaotieshu()<<endl;
for(int i=0;i<vgaotie.size();i++)
{
if(vgaotie[i].getNumber()!="0")
outfile<<vgaotie[i];
}
outfile.close();
/*
//test
cout<<getGaotieshu()<<endl;
for(int i=0;i<vgaotie.size();i++)
cout<<vgaotie[i];
*/
}
2、通过fopen()、fscanf()、fprintf()函数读取文件并复制到另一个文件中,同时打印在屏幕上。
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
int main()
{
FILE *fin,*fout;
fin=stdin;
fout=stdout;
fin = fopen("test.txt","rb"); //定义输入文件名
fout = fopen("test_out.txt","wb"); //定义输出文件名
char temp;
/*
fscanf 语法:
#include <stdio.h>
int fscanf( FILE *stream, const char *format, ... );
函数fscanf()以scanf()的执行方式从给出的文件流中读取数据. fscanf()的返回值是事实上已赋值的变量的数,如果未进行任何分配时返回EOF.
*/
while (fscanf(fin,"%c",&temp)==1) //从输入文件中读入数据
{
cout<<temp;
fprintf(fout,"%c",temp);
}
fclose(fin);
fclose(fout); //关闭文件,可省略
return 0;
}
3、通过freopen()输入输出重定向来进行操作(这里只展示部分操作),可参考通讯录管理系统的文件读写。
int main()
{
freopen("1.txt","r",stdin); //操作记录从文件1.txt中输入数据
if(freopen("1.txt","r",stdin)==NULL)//(这里与fopen读取是否成功的判断方式不同)
{
cout<<"Can't read!"<<endl;
return 0;
}
freopen("2.txt","w",stdout); //操作输出结果输出到自动创建的文件2.txt中
fclose(stdin);
fclose(stdout);
freopen("小光的通讯录.txt","w",stdout);//操作最后的通讯录结果(所有联系人)输出到"通讯录.txt"中
fclose(stdout);
return 0;
}
//fopen读取是否成功的判断
fpSrc = fopen( "c:\tmp\students.txt", "rb");
if( fpSrc == NULL )
{
printf( "Failed to open the file.");
return 0;
}
Java文件读写(举例):
1、通过FileInputStream与FileOutputStream文件输入输出流进行读写(以文本文件复制为例)
此段代码采用文件输入输出流,因此文档格式不限,可以是图片、视频等多种文件格式。可用于文档的复制等。
另外此段代码更可用于格式的转换,感觉超赞!测试将音乐格式.m4a转换为视频格式.mp4,视频保留了音效,界面由于本身就没有故是黑屏效果。也测试将mp4格式转换为mp3格式将音效提取出来,保留了音效。
注意内容:
int by = 0;
while ((by = fis.read()) != -1) { fos.write(by); }
2、通过FileReader搭配BufferedReader、FileWriter搭配BufferedWriter进行读写(以文本文件复制为例)
此段代码仅适用于文本文档读写复制。
注意内容:
String line;
while ((line = bw1.readLine()) != null) {
bw2.write(line);
bw2.newLine(); //换行
}
1、2源代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.File;
import java.io.BufferedReader;
import java.io.BufferedWriter;
/*
* 复制文本
*
* 数据源:从哪里来
* a.txt -- 读取数据
* 目的地:
* b.txt
* */
public class IOTest {
//文件复制(适合所有文件)
/*
* public static void main(String[] args) throws IOException {
*
* FileInputStream fis = new FileInputStream("C:\Users\Administrator\Desktop\argc.txt");// 封装数据源对象
* FileOutputStream fos = new FileOutputStream("C:\Users\Administrator\Desktop\argc1.txt");// 封装目的地
* //此处可对FileInputStream与FileOutputStream使用BufferInputStream和BufferOutputStream进行包装嵌套来修饰,从而提高读写速度,详见下面的例子。
* int by = 0;
* while ((by = fis.read()) != -1) { fos.write(by); } // 释放资源的时候先关闭谁都可以
* fis.close(); fos.close(); }
*/
//格式转换
// public static void main(String[] args) throws IOException {
//
// FileInputStream fis = new FileInputStream("C:\Users\Administrator\Desktop\柠檬酸.mp4");// 封装数据源对象
// FileOutputStream fos = new FileOutputStream("C:\Users\Administrator\Desktop\请你吃柠檬.mp3");// 封装目的地
// // 此处可对FileInputStream与FileOutputStream使用BufferInputStream和BufferOutputStream进行包装嵌套来修饰,从而提高读写速度,详见下面的例子。
// int by = 0;
// while ((by = fis.read()) != -1) {
// fos.write(by);
// } // 释放资源的时候先关闭谁都可以
// fis.close();
// fos.close();
// }
//文件转换(仅适用于文本文档)
public static void main(String[] args) throws IOException {
String pathname = "C:\Users\Administrator\Desktop\argc.txt";
String pathname1 = "C:\Users\Administrator\Desktop\argc2.txt";
File f = new File(pathname);
File s = new File(pathname1);
FileReader fw1 = new FileReader(f);
BufferedReader bw1 = new BufferedReader(fw1);
FileWriter fw2 = new FileWriter(s);
BufferedWriter bw2 = new BufferedWriter(fw2);
String line;
// Scanner cin=new Scanner(System.in);
while ((line = bw1.readLine()) != null) {
bw2.write(line);
bw2.newLine(); //换行
}
bw2.close();
bw1.close();
}
}
3、Java I/O是典型的装饰模式,现在对一些类进行继承和重写来重新对Java I/O进行装饰改造。
下面涉及使用BufferInputStream和BufferOutputStream对FileInputStream与FileOutputStream进行包装嵌套来修饰,从而提高读写速度。
主要改造点:自定义一个装饰器EncryptedOutputStream类对输出流进行加工。
可参考装饰模式:
装饰模式
例(InputStream):
package io_test;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class IOTest_InputStream {
public static void main(String[] args) throws IOException {
DataInputStream din = null;
try {
din = new DataInputStream(
new BufferedInputStream(
new FileInputStream("iotest.txt")
)
);
byte bs[] = new byte[din.available()];
din.read(bs);
String content = new String(bs);
System.out.println("文件内容==="+content);
}finally {
din.close();
}
}
}
例(OutputStream)(新增了自定义的装饰器EncryptedOutputStream):
package io_test;
import java.io.IOException;
import java.io.OutputStream;
public class EncrypteOutputStream extends OutputStream {
private OutputStream os = null;
public EncrypteOutputStream(OutputStream os) {
this.os = os;
}
@Override
public void write(int a) throws IOException {
a=a+2;
if(a>=(97+26)) {
a=a-26;
}
this.os.write(a);
}
}
package io_test;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOTest {
public static void main(String[] args) throws IOException {
DataOutputStream dout = new DataOutputStream(
new BufferedOutputStream(
new EncrypteOutputStream(
new FileOutputStream("iotest.txt"))));
dout.write("abcd".getBytes());
dout.close();
}
}
iotest.txt文件下就会输出:cdef(改造之前应该为abcd)
4、文件复制(直接复制文件,使用文件流进行操作)(参考1)(这里对文本文档进行末尾添加操作,而不是覆盖已有内容)
注意内容:
//Scanner cin = new Scanner(f); //以变量类型方式读取文件
if(!f.exists()) {
f.createNewFile();
}
FileInputStream in=new FileInputStream(f); //直接以文件流方式读取文件
byte[] b = new byte[1024];
int c;
FileOutputStream out = new FileOutputStream(fout,true); //可追加,可更新文件后重写
while((c=in.read(b))!=-1) {
for(int i=0;i<c;i++) {
out.write(b[i]);
}
}
源代码:
package txt文件读取; //以文件流方式读取
import java.io.BufferedInputStream; //添加buffer缓冲区,使文件读写速度更快
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
//import java.io.FileNotFoundException;
import java.io.FileOutputStream;
//import java.io.FileWriter;
import java.io.IOException;
//import java.util.Scanner;
public class copy {//直接复制文件,使用文件流进行操作,这里选用
public static void main(String[] args) throws IOException {
String path = "C:\Users\Dell\Desktop\学生成绩1.txt";
File f = new File(path);
File fout = new File("C:\Users\Dell\Desktop\学生成绩2.txt"); //不同于path的命名方式
//Scanner cin = new Scanner(f); //以变量类型方式读取文件
if(!f.exists()) {
f.createNewFile();
}
FileInputStream in=new FileInputStream(f); //直接以文件流方式读取文件
byte[] b = new byte[1024];
int c;
FileOutputStream out = new FileOutputStream(fout,true); //可追加,可更新文件后重写
while((c=in.read(b))!=-1) {
for(int i=0;i<c;i++) {
out.write(b[i]);
}
}
BufferedInputStream bufr = new BufferedInputStream(new FileInputStream(f)); //对文件流读取方式进行改造,使文件读取速度更快
BufferedOutputStream bufout = new BufferedOutputStream(new FileOutputStream(fout,true));
while((c=bufr.read(b))!=-1) {
for(int i=0;i<c;i++) {
bufout.write(b[i]);
}
}
in.close();
out.close();
bufr.close();
bufout.close();
}
}
5、从键盘读入写到文件内部(采用PrintStream写入文件)
源代码:
package txt文件读取;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;
public class keyborad {
public static void main(String[] args) throws FileNotFoundException {
String path = "C:\Users\Dell\Desktop\学生成绩2.txt";
Scanner cin = new Scanner(System.in);
File f = new File(path);
PrintStream p = new PrintStream(f);
String s = null;
while(true) { //!s.equals("end"): Exception in thread "main" java.lang.NullPointerExceptionat txt文件读取.keyborad.main(keyborad.java:16)
s=cin.next();
if(s.equals("end")) {
break; //s=="end"无效,跳不出循环,证明Sting类型应当用equals比较是否一致
}
p.println(s);
}
cin.close();
p.close();
}
}
6、从文件读入内容进行操作后(变换大小写,统计文件字符数、行数等)输出到新文件中并打印到屏幕上(BufferedReader读入,PrintStream写入)
注意内容:
char c;
for(int i=0;i<str.length();i++) {
c=str.charAt(i);
if(c==' '||c=='
'||c==' ');
else count++;
//System.out.print(Character.toLowerCase(c));
System.out.print(Character.toUpperCase(c)); //这里只按大写为例
p.print(Character.toUpperCase(c));
//nNaAmMeE //大小写一起使用时效果
}
// str.toUpperCase(); //无用,没有产生效果
// str.toLowerCase();
// System.out.println(str);
源代码:
package txt文件读取;
//以BufferReader方式读取
import java.io.BufferedReader;
import java.io.File;
//import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
public class Systemout {
public static void main(String[] args) throws IOException {
String path = "C:\Users\Dell\Desktop\学生成绩2.txt";
//将学生成绩2中文档经过转化后直接存到学生成绩3中
File f = new File("C:\Users\Dell\Desktop\学生成绩3.txt");
PrintStream p = new PrintStream(f);
// FileReader fr = new FileReader(f); //并不好用
BufferedReader bfr = new BufferedReader(new FileReader(path));
String str = null;
// int lineNumber = 0; //统计文本文件行数
int count=0; //统计字符个数
while ((str = bfr.readLine()) != null) {
// lineNumber++;
// System.out.println(lineNumber + " " + str);
//Character c;
char c;
for(int i=0;i<str.length();i++) {
c=str.charAt(i);
if(c==' '||c=='
'||c==' ');
else count++;
//System.out.print(Character.toLowerCase(c));
System.out.print(Character.toUpperCase(c)); //这里只按大写为例
p.print(Character.toUpperCase(c));
//nNaAmMeE //大小写一起使用时效果
}
// str.toUpperCase(); //无用,没有产生效果
// str.toLowerCase();
// System.out.println(str);
System.out.println();
p.println();
}
System.out.print(count);
bfr.close();
p.close();
}
}
7、以变量方式读取文件进行操作,使用Scanner读入(按格式),使用PrintStream写入(以计算学生成绩为例)
注意内容:
该程序需要用到文本文档,将在下面给出。
String path = "C:\Users\Dell\Desktop\学生成绩1.txt";
File f = new File(path);
Scanner cin = new Scanner(f);
//像正常从键盘键入一样(Scanner cin = new Scanner(System.in);):
String s[] = new String[4];
for(int i=0;i<4;i++) {
s[i]=cin.next();
}
源代码:
package txt文件读取; //以变量方式读取,使用Scanner,使用PrintStream写入
//按排序顺序输出,同奖学金评定,可使用类的方式对平均分进行求出并对对象排序输出
import java.io.File;
//import java.io.FileNotFoundException;
//import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
public class txt {
public static void main(String[] args) throws IOException {
String path = "C:\Users\Dell\Desktop\学生成绩1.txt";
File f = new File(path);
Scanner cin = new Scanner(f);
System.out.println("文件的部分属性:");
System.out.println("文件路径:"+f.getPath());
System.out.println("文件名:"+f.getName());
System.out.println("文件可读性:"+f.canRead());
System.out.println("文件可写性:"+f.canWrite());
String s[] = new String[4];
for(int i=0;i<4;i++) {
s[i]=cin.next();
}
String name[] = new String [4];
int count = 0;
double score[][] = new double [4][4];
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if(j==0) {
name[count]=cin.next();
count++;
}
else {
score[i][j-1]=cin.nextDouble();
}
}
score[i][3]=(score[i][0]+score[i][1]+score[i][2])/3;
}
cin.close();
System.out.println("初始数据:");
for(int i=0;i<4;i++) {
System.out.print(s[i]+" ");
}
System.out.println();
for(int i=0;i<4;i++) {
System.out.print(name[i]+" ");
for(int j=0;j<4;j++) {
System.out.print(score[i][j]+" ");
}
System.out.println();
}
//文件写入:(排序前数据)
File p = new File("C:\Users\Dell\Desktop\学生成绩2.txt");
if(!p.exists()){
p.createNewFile();
}
PrintStream out=new PrintStream(p);
out.println("初始数据:");
for(int i=0;i<4;i++) {
out.print(s[i]+" ");
}
out.println();
for(int i=0;i<4;i++) {
out.print(name[i]+" ");
for(int j=0;j<4;j++) {
out.print(score[i][j]+" ");
}
out.println();
}
//排序:
String a;
double b[] = new double[4];
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if(score[i][3]>=score[j][3]) {
a=name[i];
name[i]=name[j];
name[j]=a;
for(int k=0;k<4;k++) {
b[k]=score[i][k];
score[i][k]=score[j][k];
score[j][k]=b[k];
}
}
}
}
System.out.println("排序后数据:");
for(int i=0;i<4;i++) {
System.out.print(s[i]+" ");
}
System.out.println();
for(int i=0;i<4;i++) {
System.out.print(name[i]+" ");
for(int j=0;j<4;j++) {
System.out.print(score[i][j]+" ");
}
System.out.println();
}
//文件写入:(排序后数据)
out.println();
out.println("排序后数据:");
for(int i=0;i<4;i++) {
out.print(s[i]+" ");
}
out.println();
for(int i=0;i<4;i++) {
out.print(name[i]+" ");
for(int j=0;j<4;j++) {
out.print(score[i][j]+" ");
}
out.println();
}
out.close();
}
}
该程序需要的文档:
学生成绩1.txt
姓名 数学 物理 化学
张三 98 80 89
李四 91 88 87
王五 93 89 78
周六 90 90 89
结果展示文档(结果展示,自动生成):
学生成绩2.txt
初始数据:
姓名 数学 物理 化学
张三 98.0 80.0 89.0 89.0
李四 91.0 88.0 87.0 88.66666666666667
王五 93.0 89.0 78.0 86.66666666666667
周六 90.0 90.0 89.0 89.66666666666667
排序后数据:
姓名 数学 物理 化学
周六 90.0 90.0 89.0 89.66666666666667
张三 98.0 80.0 89.0 89.0
李四 91.0 88.0 87.0 88.66666666666667
王五 93.0 89.0 78.0 86.66666666666667