7.12~7.13学习总结

本文展示了Java中的文件操作,包括创建目录、列出文件、字节流和字符流的转换、文件读取以及文件拷贝。还讨论了字节数组输入流、缓冲流、数据流、对象流的使用,以及如何处理编码问题和避免乱码。此外,文章提到了文件的分割与合并方法,并涉及多线程和排序算法在处理IO问题时的应用。
摘要由CSDN通过智能技术生成
 public static void main(String[] args)
    {
        File dir=new File("D:\\小花花");
        boolean flag =dir.mkdir();
        System.out.println(flag);
        File dirs=new File("D:\\小花花\\你爸爸");
        dirs.mkdirs();
       String[]a=dir.list();//列出下一级;字符串数组
        for(String s:a)
        {
            System.out.println(s);
        }
        File []file=dir.listFiles(); //下级对象
        for(File s:file)
        {
            System.out.println(s.getAbsolutePath());
        }

        //类出所有盘符;
        File[] roots=dir.listRoots();
        for(File s:roots)
        {
            System.out.println(s.getAbsolutePath());
        }
      






    }

/*
false
你爸爸
D:\小花花\你爸爸
C:\
D:\
E:\


*/

在文件里面可能会出现这个文件存在,但是指针为空的情况,可能是由于有些文件无权限1访问造成的;所以最好不要用指针为空的1情况来判断文件是否存在。

字节和字符的转换问题:

  public static void main(String[]args) throws UnsupportedEncodingException {//默认使用工程下的字符集

        String msg="性命生命使命a";
        //编码:字节数组;
        byte[]datas=msg.getBytes();
        System.out.println(datas.length);
        //可以编码成其他字符集;
        datas=msg.getBytes("UTF-8");
        System.out.println(datas.length);
        msg=new String(datas,0, datas.length,"utf8");
        System.out.println(msg);
        //如果乱码:
        // 1.字节数不够乱码;
        //2.字符集不统一


    }
/*
19
19
性命生命使命a


*/

单个字符的文件读取:

class Main
{
   public static void main(String[]args)
   {
      File src=new File("小花花");
      InputStream is=null;
       try {
           is= new FileInputStream(src);
           int temp;
           while((temp=is.read())!=-1)
           {
               System.out.println((char)temp);
           }
       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally
       {
           if(is!=null) {
               try {
                   is.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }


   }
}
/*
w
e
i
 
l
i
a
n
g
 
h
u
a
 
k
a
i
 
m
e
n
g
 
q
i
n
g
 
y
a
n
g

*/
class Main
{
   public static void main(String[]args)
   {
      File src=new File("小花花");
      InputStream is=null;
       try {
           is= new FileInputStream(src);
           byte[]car=new byte[1024];
           int len;

           while((len=is.read(car))!=-1)//一段字节去读,然后编码成字符串;
           {
              String str=new String(car,0,len);
              System.out.println(str);
           }
       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally
       {
           if(is!=null) {
               try {
                   is.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }


   }
}
/*

wei liang hua kai meng qing yang

*/

字符流和字节流的区别主要在于:字符流是只能处理字符,但是无法处理其他的图片声音,但是字符六处理字符可以包含中文,而且不需要编码和解码,几乎很少出现乱码问题,字节流在不同的模式下装数组的数如果没有控制好,很容易乱码,所以全字符处理建议用字符流,如果是声音图片等就只能用字节流 

//使用文件输入流和输出流达到文件的拷贝

//输入流和输出流要记得打开和关闭,先打开的后关闭
class Main
{
    public static void copy1(String file1path,String file2path)
    {
        File file1=new File(file1path);
        File file2=new File(file2path);
        InputStream is=null;
        OutputStream os=null;
        try {
            is=new FileInputStream(file1);
            os=new FileOutputStream(file2);
            byte[]flush=new byte[1024];
            int len=-1;
            while((len= is.read(flush))!=-1)
            {
               os.write(flush,0,len);

            }os.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally
        {
            if(os!=null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is!=null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


   public static void main(String[]args)
   {
       String file1="C:\\Users\\zplaz\\Pictures\\Camera Roll\\微信图片_20230420163132.jpg";
       String file2="泥巴巴2.jpg";
       copy1(file1,file2);
   }
}

字节数组输入流,字节数组不要太大,字节数组不要释放,也就是关闭;       

装饰模式:

缓冲流直接加在要提升输入输出流上面的上面,可以提高性能

 缓冲流内部有缓冲,只有达到一定的量才会被写出,如果输入的内容太少,要记得强制刷新一下,和缓冲流放一起不需要释放,jre会自动释放缓冲区,其中包括最低层的字节流和字符流;缓冲流放到字节流和字符流的外层,而不是处理流;

数据流:先写入,后读取,并且要按照写入的数据类型顺序来读取,就算没用该数据,也要对应读出来;对象流:特点和数据流类似,多了一个读写对象,序列化:不是所有的对象都可以序列化:如果某个数据不需要序列化,可以加上关键字,transient,

实例:

public class Main
{
    public static void main(String[]args) throws IOException, ClassNotFoundException {
       FileOutputStream baos=new FileOutputStream("小花花.text");
        ObjectOutputStream dos=new ObjectOutputStream(new BufferedOutputStream(baos));
        dos.writeUTF("超级无敌想小麻子");
        dos.writeInt(18);
        dos.writeBoolean(false);
        Employee emp=new Employee("小麻子",10000);
        dos.writeObject(new Date());
        dos.writeObject(emp);

        dos.flush();




        ObjectInputStream dis=new ObjectInputStream(new BufferedInputStream(new FileInputStream("小花花.text")));
        String msg=dis.readUTF();
        int age=dis.readInt();
        boolean flag=dis.readBoolean();
        Date day= (Date) dis.readObject();
        Employee e=(Employee) dis.readObject();

        System.out.println(e.getName()+"---"+e.getSalary());

    }
}
class Employee implements java.io.Serializable
{
    private  transient String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}


/*
null---10000.0

*/

打印流:打印流要记得释放资源,释放里面的字节流;

public class Main
{
    public static void main(String[]args) throws FileNotFoundException {
        PrintStream ps=System.out;
        ps.println("小麻子");//在控制台打印
        ps=new PrintStream(new BufferedOutputStream(new FileOutputStream("小花花")),true);
        ps.println("小麻子");//在文件中打印
        ps.close();
        //重定向输出端到文件
        System.setOut(ps);
        System.out.println("小麻子真的很喜欢小饺子");
        //重定向到控制台
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));//true为是否是自动刷新
        System.out.println("小麻子爱吃草");
        
    }
}

文件分割。合并方法的封装:

public class Main
{
    //源头
    private File src;
    //目的地(文件夹)
    private String destDir;
    //所有分割后的存储路径
    private List<String> desPaths;
    //每块大小
    private int blockSize;
    //块数,多少块
    private int size;

    public Main(String srcPath, String destDir, int blockSize) {
        this.src = new File(srcPath);
        this.destDir = destDir;
        this.blockSize = blockSize;
        this.desPaths =new ArrayList<String>();
        init();
    }
    public static void main(String[]args) throws IOException {
        Main m=new Main("D:\\.txt", "dest",1024);
        m.splitDetails();
        m.merge("小花花.text");
    }
    private void init()
    {
        long len=src.length();
        //多少块
        this.size=(int)Math.ceil(len*1.0/blockSize);
        //路径
        for(int i=0;i<size;i++)
        {
            this.desPaths.add(this.destDir+"/"+i+"-"+this.src.getName());
        }
    }
    
    public void merge(String desPath) throws IOException {
        OutputStream os=new BufferedOutputStream(new FileOutputStream(desPath));
        Vector<InputStream>vi=new Vector<InputStream>();
        SequenceInputStream sis=null;
        for(int i=0;i<size;i++)
        {
            vi.add(new BufferedInputStream(new FileInputStream(desPaths.get(i))));
        }
        sis=new SequenceInputStream(vi.elements());
            byte[]flush=new byte[1024];
            int len=-1;
            while((len=sis.read(flush))!=-1) {

                os.write(flush, 0, len);

            }


        sis.close();
        os.close();



    }
    
    public void splitDetails() throws IOException {
        long len=src.length();
        int beginPos=0;
        int actualSize=(int)(blockSize>len?len:blockSize);
        for(int i=0;i<size;i++)
        {
            beginPos=i*blockSize;
            if(i==size-1)actualSize=(int)len;
            else
                actualSize=blockSize;
            len-=actualSize;
            split(i,beginPos,actualSize);
        }
    }
    //分割
   private void split(int i,int beginPos,int actualSize) throws IOException {//指定起始位置,读取其他所有内容
        RandomAccessFile raf=new RandomAccessFile(this.src,"r");
        RandomAccessFile raf2=new RandomAccessFile(this.desPaths.get(i),"rw");
        raf.seek(beginPos);
        byte[]flush=new byte[1024];
        int len=-1;
        while((len=raf.read(flush))!=-1)
        {
            if(actualSize>len)
            {
                raf2.write(flush,0,len);
                actualSize-=len;
            }
            else
            {
                raf2.write(flush,0,actualSize);
                break;
            }
        }raf2.close();raf.close();
    }
}


IOcommons环境搭建:

多线程:方法间的调用,一条路径,多线程,多条路径。

写题总结:

C - Standings

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct
{
    int id;
    long long a;
    long long sum;


} ha;
ha h[200010];

bool cmp(ha x,ha y)
{
    if(x.a*y.sum !=y.a*x.sum)
    return x.a*y.sum > y.a*x.sum;
    else
        return x.id<y.id;
}

int main()
{
//没有转型,会超出int范围


    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {

        int j,k;
        scanf("%d %d",&j,&k);
        h[i].id=i;
        h[i].a=j;
        h[i].sum=j+k;

    }
    //Quilkll(1,n);
    sort(h+1,h+n+1,cmp);
    for(int i=1; i<=n; i++)
    {
        printf("%d ",h[i].id);
    }
    return 0;


}

这个题如果直接去套公式的话,是不可以的,double精度会爆炸,所以不要用除法,可以用乘法,吧除以某个数乘以到另一边去,然后用sort排序就可以了,反正冒泡排序会时间超限,其实这个题目里面暗含了一个条件,暗示了sort不仅要重构比较公式,更重要的是如果两个公式值相等,那么就按照原来的排序,不可以变序,如果是直接用sort并且像下面这样简单的构造的话,只可以拿到20/23;

bool cmp(ha x,ha y)
{
    return x.a*y.sum > y.a*x.sum;
}

直接上代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct
{
    int id;
    long long a;
    long long sum;


} ha;
ha h[200010];

bool cmp(ha x,ha y)
{
    if(x.a*y.sum !=y.a*x.sum)
    return x.a*y.sum > y.a*x.sum;
    else
        return x.id<y.id;
}

int main()
{
//没有转型,会超出int范围


    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {

        int j,k;
        scanf("%d %d",&j,&k);
        h[i].id=i;
        h[i].a=j;
        h[i].sum=j+k;

    }
    //Quilkll(1,n);
    sort(h+1,h+n+1,cmp);
    for(int i=1; i<=n; i++)
    {
        printf("%d ",h[i].id);
    }
    return 0;


}

注意:sum要用longlong;

A - 排序

有点开心第一次写这么简单的排序题:但是还是有坑,题目规定

 所以可以看到代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[100010];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {

        scanf("%d",&a[i]);

    }
    sort(a,a+n);

    for(int i=0;i<n;i++)
    {
        if(i==n-1)
        printf("%d\n",a[i]);
        else
            printf("%d ",a[i]);


    }
    return 0;



}

B - Medicine

刚看到这题看了一个小时才看懂题目QAQ,所以我现在最想做的就是来说一下题意:第一行,n表示药物的种类,m表示这个药物的片数,从第二行开始表示在ai天内都要吃bi片i第i种药,也就是第二行的例子表示,在接下来的6天里,都要吃第一种药8片,然后题目要求的是最早在第几天这个人吃的药的片数会小于或者这个m,我的思路是:先将这几种药的吃的天数和每天吃多少粒进行打包,然后按照它们的天数进行排序,然后从最少的天数去一一减掉,后面没过,其实一一减去里面有大量重复的情况,可以按照每一种的天数去减,这样就能减小时间复杂度:

下面来说说具体步骤:

1.将所有种类的总片数也就是一天最多吃的片数求出来;

2.将输入的出第一行外的数据两个都打包成结构体;按照天数排序;

3.然后遍历数组比较z和m从天数最少的b的片数开始减,当z开始小于或者等于m的时候,就可以将此时的天数拿出来了;

4.到那时这时候的天数是刚好满足,消耗完了,这时候的天数+1才是刚好真的没有那些减去的药了,这时候的天数才是答案;

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct
{
    int a;
    int b;
} ha;
bool cmp(ha x,ha y)
{

    return x.a>y.a;
}
ha h[300010];
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    long long z=0;
    for(int i=0; i<n; i++)
    {
        scanf("%d %d",&h[i].a,&h[i].b);

    }
    for(int i=0;i<n;i++)
    {
        z+=h[i].b;
    }
    sort(h,h+n,cmp);

    long long day=0;



    int i;
    for( i=n-1;i>=0;i--)
    {
        if(z<=k)break;
        z-=h[i].b;


    }
    day=h[i+1].a+1;

    printf("%d",day);
    return 0;

}

今日份心灵鸡汤已送达:即使说了那么多丧气的话,也一直在努力生活啊,表面泄气就好啦,内心一定要偷偷给自己鼓劲儿!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值